Class: GraphQL::InternalRepresentation::Node
- Inherits:
-
Object
- Object
- GraphQL::InternalRepresentation::Node
- Defined in:
- lib/graphql/internal_representation/node.rb
Defined Under Namespace
Classes: NoTypedChildren
Constant Summary collapse
- 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 =
NoTypedChildren.new
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.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/graphql/internal_representation/node.rb', line 72 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.
61 62 63 |
# File 'lib/graphql/internal_representation/node.rb', line 61 def ast_nodes @ast_nodes end |
#definitions ⇒ Array<GraphQL::Field> (readonly)
Returns Field definitions for this node (there should only be one!).
64 65 66 |
# File 'lib/graphql/internal_representation/node.rb', line 64 def definitions @definitions end |
#name ⇒ String (readonly)
Returns the name this node has in the response.
21 22 23 |
# File 'lib/graphql/internal_representation/node.rb', line 21 def name @name end |
#owner_type ⇒ GraphQL::ObjectType
24 25 26 |
# File 'lib/graphql/internal_representation/node.rb', line 24 def owner_type @owner_type end |
#parent ⇒ InternalRepresentation::Node?
70 71 72 |
# File 'lib/graphql/internal_representation/node.rb', line 70 def parent @parent end |
#query ⇒ GraphQL::Query (readonly)
165 166 167 |
# File 'lib/graphql/internal_representation/node.rb', line 165 def query @query end |
#return_type ⇒ GraphQL::BaseType (readonly)
Returns The expected wrapped type this node must return.
67 68 69 |
# File 'lib/graphql/internal_representation/node.rb', line 67 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.
58 59 60 |
# File 'lib/graphql/internal_representation/node.rb', line 58 def scoped_children @scoped_children end |
Instance Method Details
#==(other) ⇒ Object
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/graphql/internal_representation/node.rb', line 101 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
116 117 118 |
# File 'lib/graphql/internal_representation/node.rb', line 116 def arguments @query.arguments_for(self, definition) end |
#ast_node ⇒ Object
127 128 129 |
# File 'lib/graphql/internal_representation/node.rb', line 127 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.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/graphql/internal_representation/node.rb', line 139 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
120 121 122 123 124 125 |
# File 'lib/graphql/internal_representation/node.rb', line 120 def definition @definition ||= begin first_def = @definitions.first first_def && @query.get_field(@owner_type, first_def.name) end end |
#definition_name ⇒ Object
112 113 114 |
# File 'lib/graphql/internal_representation/node.rb', line 112 def definition_name definition && definition.name end |
#initialize_copy(other_node) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/graphql/internal_representation/node.rb', line 88 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
131 132 133 134 135 |
# File 'lib/graphql/internal_representation/node.rb', line 131 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
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/graphql/internal_representation/node.rb', line 167 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.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/graphql/internal_representation/node.rb', line 31 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 |