Skip to content

Commit 3872c32

Browse files
authored
Merge pull request rmosolgo#342 from rmosolgo/use-typename-nodes
refactor(Parser) parse type conditions as TypeNames, not strings
2 parents c78d24b + 5ded15e commit 3872c32

File tree

9 files changed

+297
-288
lines changed

9 files changed

+297
-288
lines changed

lib/graphql/language/generation.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ def generate(node, indent: "")
3636
out
3737
when Nodes::FragmentDefinition
3838
out = "#{indent}fragment #{node.name}"
39-
out << " on #{node.type}" if node.type
39+
if node.type
40+
out << " on #{generate(node.type)}"
41+
end
4042
out << generate_directives(node.directives)
4143
out << generate_selections(node.selections, indent: indent)
4244
out
@@ -46,7 +48,9 @@ def generate(node, indent: "")
4648
out
4749
when Nodes::InlineFragment
4850
out = "#{indent}..."
49-
out << " on #{node.type}" if node.type
51+
if node.type
52+
out << " on #{generate(node.type)}"
53+
end
5054
out << generate_directives(node.directives)
5155
out << generate_selections(node.selections, indent: indent)
5256
out

lib/graphql/language/parser.rb

Lines changed: 270 additions & 270 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/graphql/language/parser.y

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ rule
214214
ELLIPSIS name_without_on directives_list_opt { return make_node(:FragmentSpread, name: val[1], directives: val[2], position_source: val[0]) }
215215

216216
inline_fragment:
217-
ELLIPSIS ON name directives_list_opt selection_set {
217+
ELLIPSIS ON type directives_list_opt selection_set {
218218
return make_node(:InlineFragment, {
219219
type: val[2],
220220
directives: val[3],
@@ -232,7 +232,7 @@ rule
232232
}
233233

234234
fragment_definition:
235-
FRAGMENT fragment_name_opt ON name_without_on directives_list_opt selection_set {
235+
FRAGMENT fragment_name_opt ON type directives_list_opt selection_set {
236236
return make_node(:FragmentDefinition, {
237237
name: val[1],
238238
type: val[3],

lib/graphql/language/parser_tests.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def self.included(test)
6565
assert fragment_def.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
6666
assert_equal "moreNestedFields", fragment_def.name
6767
assert_equal 1, fragment_def.selections.length
68-
assert_equal "NestedType", fragment_def.type
68+
assert_equal "NestedType", fragment_def.type.name
6969
assert_equal 1, fragment_def.directives.length
7070
assert_equal [20, 13], fragment_def.position
7171
end
@@ -173,7 +173,7 @@ def self.included(test)
173173
let(:typeless_inline_fragment) { query.selections[3] }
174174

175175
it "gets the type and directives" do
176-
assert_equal "OtherType", inline_fragment.type
176+
assert_equal "OtherType", inline_fragment.type.name
177177
assert_equal 2, inline_fragment.selections.length
178178
assert_equal 1, inline_fragment.directives.length
179179
end

lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def validate(context)
2222

2323
context.visitor[GraphQL::Language::Nodes::Document].leave << ->(doc_node, parent) {
2424
spreads_to_validate.each do |frag_spread|
25-
fragment_child_name = context.fragments[frag_spread.node.name].type
25+
fragment_child_name = context.fragments[frag_spread.node.name].type.name
2626
fragment_child = context.schema.types.fetch(fragment_child_name, nil) # Might be non-existent type name
2727
if fragment_child
2828
validate_fragment_in_scope(frag_spread.parent_type, fragment_child, frag_spread.node, context, frag_spread.path)

lib/graphql/static_validation/rules/fragment_types_exist.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ def validate(context)
1818

1919
def validate_type_exists(node, context)
2020
return unless node.type
21-
type = context.schema.types.fetch(node.type, nil)
21+
type_name = node.type.name
22+
type = context.schema.types.fetch(type_name, nil)
2223
if type.nil?
23-
context.errors << message("No such type #{node.type}, so it can't be a fragment condition", node, context: context)
24+
context.errors << message("No such type #{type_name}, so it can't be a fragment condition", node, context: context)
2425
GraphQL::Language::Visitor::SKIP
2526
end
2627
end

lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ def validate(context)
1919
private
2020

2121
def validate_type_is_composite(node, context)
22-
type_name = node.type
23-
return unless type_name
24-
type_def = context.schema.types[type_name]
25-
if type_def.nil? || !type_def.kind.composite?
26-
context.errors << message("Invalid fragment on type #{type_name} (must be Union, Interface or Object)", node, context: context)
27-
GraphQL::Language::Visitor::SKIP
22+
node_type = node.type
23+
if node_type.nil?
24+
# Inline fragment on the same type
25+
else
26+
type_name = node_type.to_query_string
27+
type_def = context.schema.types.fetch(type_name, nil)
28+
if type_def.nil? || !type_def.kind.composite?
29+
context.errors << message("Invalid fragment on type #{type_name} (must be Union, Interface or Object)", node, context: context)
30+
GraphQL::Language::Visitor::SKIP
31+
end
2832
end
2933
end
3034
end

lib/graphql/static_validation/type_stack.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def initialize(schema, visitor)
5757
module FragmentWithTypeStrategy
5858
def push(stack, node)
5959
object_type = if node.type
60-
stack.schema.types.fetch(node.type, nil)
60+
stack.schema.types.fetch(node.type.name, nil)
6161
else
6262
stack.object_types.last
6363
end
@@ -86,7 +86,7 @@ module InlineFragmentStrategy
8686
extend FragmentWithTypeStrategy
8787
module_function
8888
def push_path_member(stack, node)
89-
stack.path.push("...#{node.type ? " on #{node.type}" : ""}")
89+
stack.path.push("...#{node.type ? " on #{node.type.to_query_string}" : ""}")
9090
end
9191
end
9292

spec/graphql/language/parser_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
assert fragment.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
2626
assert_equal nil, fragment.name
2727
assert_equal 1, fragment.selections.length
28-
assert_equal "NestedType", fragment.type
28+
assert_equal "NestedType", fragment.type.name
2929
assert_equal 1, fragment.directives.length
3030
assert_equal [2, 7], fragment.position
3131
end

0 commit comments

Comments
 (0)