Class: GraphQL::InternalRepresentation::Node
- Inherits:
-
Object
- Object
- GraphQL::InternalRepresentation::Node
- Defined in:
- lib/graphql/internal_representation/node.rb
Constant Summary
- DEFAULT_TYPED_CHILDREN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Proc.new { |h, k| h[k] = {} }
- NO_TYPED_CHILDREN =
A specialized, reusable object for leaf nodes.
Hash.new({}.freeze)
Instance Attribute Summary collapse
-
#ast_nodes ⇒ Array<Language::Nodes::AbstractNode>
readonly
AST nodes which are represented by this node.
-
#definitions ⇒ Array<GraphQL::Field>
readonly
Field definitions for this node (there should only be one!).
-
#name ⇒ String
readonly
The name this node has in the response.
-
#owner_type ⇒ GraphQL::ObjectType
readonly
-
#parent ⇒ InternalRepresentation::Node?
readonly
-
#query ⇒ GraphQL::Query
readonly
-
#return_type ⇒ GraphQL::BaseType
readonly
The expected wrapped type this node must return.
-
#scoped_children ⇒ Hash<GraphQL::BaseType, Hash<String => Node>>
readonly
These children correspond closely to scopes in the AST.
Instance Method Summary collapse
-
#==(other) ⇒ Object
-
#arguments ⇒ Object
-
#ast_node ⇒ Object
-
#deep_merge_node(new_parent, scope: nil, merge_self: true) ⇒ Object
Merge selections from
new_parent
intoself
. -
#definition ⇒ Object
-
#definition_name ⇒ Object
-
#initialize(name:, owner_type:, query:, return_type:, parent:, ast_nodes: [], definitions: []) ⇒ Node
constructor
A new instance of Node.
-
#initialize_copy(other_node) ⇒ Object
-
#inspect ⇒ Object
-
#subscription_topic ⇒ Object
-
#typed_children ⇒ Hash<GraphQL::ObjectType, Hash<String => Node>>
Each key is a ObjectType which this selection may be made on.
Constructor Details
#initialize(name:, owner_type:, query:, return_type:, parent:, ast_nodes: [], definitions: []) ⇒ Node
Returns a new instance of Node
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/graphql/internal_representation/node.rb', line 65 def initialize( name:, owner_type:, query:, return_type:, parent:, ast_nodes: [], definitions: [] ) @name = name @query = query @owner_type = owner_type @parent = parent @typed_children = nil @scoped_children = Hash.new { |h1, k1| h1[k1] = {} } @ast_nodes = ast_nodes @definitions = definitions @return_type = return_type end |
Instance Attribute Details
#ast_nodes ⇒ Array<Language::Nodes::AbstractNode> (readonly)
Returns AST nodes which are represented by this node
54 55 56 |
# File 'lib/graphql/internal_representation/node.rb', line 54 def ast_nodes @ast_nodes end |
#definitions ⇒ Array<GraphQL::Field> (readonly)
Returns Field definitions for this node (there should only be one!)
57 58 59 |
# File 'lib/graphql/internal_representation/node.rb', line 57 def definitions @definitions end |
#name ⇒ String (readonly)
Returns the name this node has in the response
14 15 16 |
# File 'lib/graphql/internal_representation/node.rb', line 14 def name @name end |
#owner_type ⇒ GraphQL::ObjectType
17 18 19 |
# File 'lib/graphql/internal_representation/node.rb', line 17 def owner_type @owner_type end |
#parent ⇒ InternalRepresentation::Node?
63 64 65 |
# File 'lib/graphql/internal_representation/node.rb', line 63 def parent @parent end |
#query ⇒ GraphQL::Query (readonly)
158 159 160 |
# File 'lib/graphql/internal_representation/node.rb', line 158 def query @query end |
#return_type ⇒ GraphQL::BaseType (readonly)
Returns The expected wrapped type this node must return.
60 61 62 |
# File 'lib/graphql/internal_representation/node.rb', line 60 def return_type @return_type end |
#scoped_children ⇒ Hash<GraphQL::BaseType, Hash<String => Node>> (readonly)
These children correspond closely to scopes in the AST. Keys may be abstract types. They’re assumed to be read-only after rewrite is finished because #typed_children is derived from them.
Using #scoped_children during the rewrite step reduces the overhead of reifying abstract types because they’re only reified after the rewrite.
51 52 53 |
# File 'lib/graphql/internal_representation/node.rb', line 51 def scoped_children @scoped_children end |
Instance Method Details
#==(other) ⇒ Object
94 95 96 97 98 99 100 101 102 103 |
# File 'lib/graphql/internal_representation/node.rb', line 94 def ==(other) other.is_a?(self.class) && other.name == name && other.parent == parent && other.return_type == return_type && other.owner_type == owner_type && other.scoped_children == scoped_children && other.definitions == definitions && other.ast_nodes == ast_nodes end |
#arguments ⇒ Object
109 110 111 |
# File 'lib/graphql/internal_representation/node.rb', line 109 def arguments @query.arguments_for(self, definition) end |
#ast_node ⇒ Object
120 121 122 |
# File 'lib/graphql/internal_representation/node.rb', line 120 def ast_node @ast_node ||= ast_nodes.first end |
#deep_merge_node(new_parent, scope: nil, merge_self: true) ⇒ Object
Merge selections from new_parent
into self
.
Selections are merged in place, not copied.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/graphql/internal_representation/node.rb', line 132 def deep_merge_node(new_parent, scope: nil, merge_self: true) if merge_self @ast_nodes |= new_parent.ast_nodes @definitions |= new_parent.definitions end new_sc = new_parent.scoped_children if new_sc.any? scope ||= Scope.new(@query, @return_type.unwrap) new_sc.each do |obj_type, new_fields| inner_scope = scope.enter(obj_type) inner_scope.each do |scoped_type| prev_fields = @scoped_children[scoped_type] new_fields.each do |name, new_node| prev_node = prev_fields[name] if prev_node prev_node.deep_merge_node(new_node) else prev_fields[name] = new_node end end end end end end |
#definition ⇒ Object
113 114 115 116 117 118 |
# File 'lib/graphql/internal_representation/node.rb', line 113 def definition @definition ||= begin first_def = @definitions.first first_def && @query.get_field(@owner_type, first_def.name) end end |
#definition_name ⇒ Object
105 106 107 |
# File 'lib/graphql/internal_representation/node.rb', line 105 def definition_name definition && definition.name end |
#initialize_copy(other_node) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/graphql/internal_representation/node.rb', line 81 def initialize_copy(other_node) super # Bust some caches: @typed_children = nil @definition = nil @definition_name = nil @ast_node = nil # Shallow-copy some state: @scoped_children = other_node.scoped_children.dup @ast_nodes = other_node.ast_nodes.dup @definitions = other_node.definitions.dup end |
#inspect ⇒ Object
124 125 126 127 128 |
# File 'lib/graphql/internal_representation/node.rb', line 124 def inspect all_children_names = scoped_children.values.map(&:keys).flatten.uniq.join(", ") all_locations = ast_nodes.map {|n| "#{n.line}:#{n.col}" }.join(", ") "#<Node #{@owner_type}.#{@name} -> #{@return_type} {#{all_children_names}} @ [#{all_locations}] #{object_id}>" end |
#subscription_topic ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/graphql/internal_representation/node.rb', line 160 def subscription_topic @subscription_topic ||= begin scope = if definition.subscription_scope @query.context[definition.subscription_scope] else nil end Subscriptions::Event.serialize( definition_name, @query.arguments_for(self, definition), definition, scope: scope ) end end |
#typed_children ⇒ Hash<GraphQL::ObjectType, Hash<String => Node>>
Each key is a ObjectType which this selection may be made on. The values for that key are selections which apply to that type.
This value is derived from #scoped_children after the rewrite is finished.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/graphql/internal_representation/node.rb', line 24 def typed_children @typed_children ||= begin if @scoped_children.any? new_tc = Hash.new(&DEFAULT_TYPED_CHILDREN) all_object_types = Set.new scoped_children.each_key { |t| all_object_types.merge(@query.possible_types(t)) } # Remove any scoped children which don't follow this return type # (This can happen with fragment merging where lexical scope is lost) all_object_types &= @query.possible_types(@return_type.unwrap) all_object_types.each do |t| new_tc[t] = get_typed_children(t) end new_tc else NO_TYPED_CHILDREN end end end |