graphql 2.3.7 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +46 -0
  3. data/lib/generators/graphql/orm_mutations_base.rb +1 -1
  4. data/lib/generators/graphql/templates/base_resolver.erb +2 -0
  5. data/lib/generators/graphql/type_generator.rb +1 -1
  6. data/lib/graphql/analysis/field_usage.rb +1 -1
  7. data/lib/graphql/analysis/query_complexity.rb +3 -3
  8. data/lib/graphql/analysis/visitor.rb +7 -6
  9. data/lib/graphql/analysis.rb +1 -1
  10. data/lib/graphql/current.rb +52 -0
  11. data/lib/graphql/dataloader/async_dataloader.rb +3 -2
  12. data/lib/graphql/dataloader/source.rb +6 -3
  13. data/lib/graphql/dataloader.rb +35 -11
  14. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
  15. data/lib/graphql/execution/interpreter/resolve.rb +10 -6
  16. data/lib/graphql/execution/interpreter/runtime.rb +29 -25
  17. data/lib/graphql/execution/interpreter.rb +2 -0
  18. data/lib/graphql/execution/lookahead.rb +10 -10
  19. data/lib/graphql/introspection/directive_type.rb +1 -1
  20. data/lib/graphql/introspection/entry_points.rb +2 -2
  21. data/lib/graphql/introspection/field_type.rb +1 -1
  22. data/lib/graphql/introspection/schema_type.rb +6 -11
  23. data/lib/graphql/introspection/type_type.rb +5 -5
  24. data/lib/graphql/invalid_null_error.rb +1 -1
  25. data/lib/graphql/language/comment.rb +18 -0
  26. data/lib/graphql/language/document_from_schema_definition.rb +55 -28
  27. data/lib/graphql/language/lexer.rb +15 -15
  28. data/lib/graphql/language/nodes.rb +24 -16
  29. data/lib/graphql/language/parser.rb +14 -1
  30. data/lib/graphql/language/printer.rb +23 -7
  31. data/lib/graphql/language/sanitized_printer.rb +1 -1
  32. data/lib/graphql/language.rb +6 -6
  33. data/lib/graphql/query/context.rb +7 -1
  34. data/lib/graphql/query/null_context.rb +2 -2
  35. data/lib/graphql/query.rb +60 -8
  36. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  37. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  38. data/lib/graphql/rubocop.rb +2 -0
  39. data/lib/graphql/schema/addition.rb +1 -0
  40. data/lib/graphql/schema/always_visible.rb +6 -2
  41. data/lib/graphql/schema/argument.rb +14 -1
  42. data/lib/graphql/schema/build_from_definition.rb +9 -1
  43. data/lib/graphql/schema/directive/flagged.rb +1 -1
  44. data/lib/graphql/schema/enum.rb +54 -20
  45. data/lib/graphql/schema/enum_value.rb +9 -1
  46. data/lib/graphql/schema/field/connection_extension.rb +1 -1
  47. data/lib/graphql/schema/field.rb +92 -37
  48. data/lib/graphql/schema/has_single_input_argument.rb +2 -1
  49. data/lib/graphql/schema/input_object.rb +27 -13
  50. data/lib/graphql/schema/interface.rb +21 -4
  51. data/lib/graphql/schema/introspection_system.rb +5 -16
  52. data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
  53. data/lib/graphql/schema/member/has_arguments.rb +14 -9
  54. data/lib/graphql/schema/member/has_fields.rb +8 -6
  55. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  56. data/lib/graphql/schema/printer.rb +1 -0
  57. data/lib/graphql/schema/resolver.rb +7 -9
  58. data/lib/graphql/schema/type_expression.rb +2 -2
  59. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  60. data/lib/graphql/schema/validator/required_validator.rb +28 -4
  61. data/lib/graphql/schema/validator.rb +2 -0
  62. data/lib/graphql/schema/visibility/migration.rb +186 -0
  63. data/lib/graphql/schema/visibility/profile.rb +523 -0
  64. data/lib/graphql/schema/visibility.rb +75 -0
  65. data/lib/graphql/schema/warden.rb +156 -10
  66. data/lib/graphql/schema.rb +283 -85
  67. data/lib/graphql/static_validation/base_visitor.rb +6 -5
  68. data/lib/graphql/static_validation/literal_validator.rb +4 -4
  69. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  70. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
  71. data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -3
  72. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
  73. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +3 -2
  74. data/lib/graphql/static_validation/rules/fields_will_merge.rb +8 -7
  75. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  76. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
  77. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  78. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  79. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  80. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +3 -3
  81. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  82. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  83. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  84. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
  85. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  86. data/lib/graphql/static_validation/validation_context.rb +17 -2
  87. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -1
  88. data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
  89. data/lib/graphql/subscriptions/event.rb +1 -1
  90. data/lib/graphql/subscriptions.rb +5 -3
  91. data/lib/graphql/testing/helpers.rb +9 -5
  92. data/lib/graphql/tracing/notifications_trace.rb +2 -2
  93. data/lib/graphql/types/relay/connection_behaviors.rb +10 -0
  94. data/lib/graphql/types/relay/edge_behaviors.rb +10 -0
  95. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  96. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  97. data/lib/graphql/version.rb +1 -1
  98. data/lib/graphql.rb +3 -0
  99. metadata +29 -8
  100. data/lib/graphql/language/token.rb +0 -34
  101. data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -22,7 +22,7 @@ module GraphQL
22
22
  field :is_repeatable, Boolean, method: :repeatable?
23
23
 
24
24
  def args(include_deprecated:)
25
- args = @context.warden.arguments(@object)
25
+ args = @context.types.arguments(@object)
26
26
  args = args.reject(&:deprecation_reason) unless include_deprecated
27
27
  args
28
28
  end
@@ -15,8 +15,8 @@ module GraphQL
15
15
  end
16
16
 
17
17
  def __type(name:)
18
- if context.warden.reachable_type?(name)
19
- context.warden.get_type(name)
18
+ if context.types.reachable_type?(name) && (type = context.types.type(name))
19
+ type
20
20
  elsif (type = context.schema.extra_types.find { |t| t.graphql_name == name })
21
21
  type
22
22
  else
@@ -19,7 +19,7 @@ module GraphQL
19
19
  end
20
20
 
21
21
  def args(include_deprecated:)
22
- args = @context.warden.arguments(@object)
22
+ args = @context.types.arguments(@object)
23
23
  args = args.reject(&:deprecation_reason) unless include_deprecated
24
24
  args
25
25
  end
@@ -20,31 +20,26 @@ module GraphQL
20
20
  end
21
21
 
22
22
  def types
23
- types = context.warden.reachable_types + context.schema.extra_types
23
+ query_types = context.types.all_types
24
+ types = query_types + context.schema.extra_types
24
25
  types.sort_by!(&:graphql_name)
25
26
  types
26
27
  end
27
28
 
28
29
  def query_type
29
- permitted_root_type("query")
30
+ @context.types.query_root
30
31
  end
31
32
 
32
33
  def mutation_type
33
- permitted_root_type("mutation")
34
+ @context.types.mutation_root
34
35
  end
35
36
 
36
37
  def subscription_type
37
- permitted_root_type("subscription")
38
+ @context.types.subscription_root
38
39
  end
39
40
 
40
41
  def directives
41
- @context.warden.directives
42
- end
43
-
44
- private
45
-
46
- def permitted_root_type(op_type)
47
- @context.warden.root_type_for_operation(op_type)
42
+ @context.types.directives.sort_by(&:graphql_name)
48
43
  end
49
44
  end
50
45
  end
@@ -52,7 +52,7 @@ module GraphQL
52
52
  if !@object.kind.enum?
53
53
  nil
54
54
  else
55
- enum_values = @context.warden.enum_values(@object)
55
+ enum_values = @context.types.enum_values(@object)
56
56
 
57
57
  if !include_deprecated
58
58
  enum_values = enum_values.select {|f| !f.deprecation_reason }
@@ -64,7 +64,7 @@ module GraphQL
64
64
 
65
65
  def interfaces
66
66
  if @object.kind.object? || @object.kind.interface?
67
- @context.warden.interfaces(@object).sort_by(&:graphql_name)
67
+ @context.types.interfaces(@object).sort_by(&:graphql_name)
68
68
  else
69
69
  nil
70
70
  end
@@ -72,7 +72,7 @@ module GraphQL
72
72
 
73
73
  def input_fields(include_deprecated:)
74
74
  if @object.kind.input_object?
75
- args = @context.warden.arguments(@object)
75
+ args = @context.types.arguments(@object)
76
76
  args = args.reject(&:deprecation_reason) unless include_deprecated
77
77
  args
78
78
  else
@@ -82,7 +82,7 @@ module GraphQL
82
82
 
83
83
  def possible_types
84
84
  if @object.kind.abstract?
85
- @context.warden.possible_types(@object).sort_by(&:graphql_name)
85
+ @context.types.possible_types(@object).sort_by(&:graphql_name)
86
86
  else
87
87
  nil
88
88
  end
@@ -92,7 +92,7 @@ module GraphQL
92
92
  if !@object.kind.fields?
93
93
  nil
94
94
  else
95
- fields = @context.warden.fields(@object)
95
+ fields = @context.types.fields(@object)
96
96
  if !include_deprecated
97
97
  fields = fields.select {|f| !f.deprecation_reason }
98
98
  end
@@ -39,7 +39,7 @@ module GraphQL
39
39
  end
40
40
 
41
41
  def inspect
42
- if (name.nil? || parent_class.name.nil?) && parent_class.respond_to?(:mutation) && (mutation = parent_class.mutation)
42
+ if (name.nil? || parent_class&.name.nil?) && parent_class.respond_to?(:mutation) && (mutation = parent_class.mutation)
43
43
  "#{mutation.inspect}::#{parent_class.graphql_name}::InvalidNullError"
44
44
  else
45
45
  super
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module Language
4
+ module Comment
5
+ def self.print(str, indent: '')
6
+ lines = str.split("\n").map do |line|
7
+ comment_str = "".dup
8
+ comment_str << indent
9
+ comment_str << "# "
10
+ comment_str << line
11
+ comment_str.rstrip
12
+ end
13
+
14
+ lines.join("\n") + "\n"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -18,21 +18,15 @@ module GraphQL
18
18
  include_built_in_directives: false, include_built_in_scalars: false, always_include_schema: false
19
19
  )
20
20
  @schema = schema
21
+ @context = context
21
22
  @always_include_schema = always_include_schema
22
23
  @include_introspection_types = include_introspection_types
23
24
  @include_built_in_scalars = include_built_in_scalars
24
25
  @include_built_in_directives = include_built_in_directives
25
26
  @include_one_of = false
26
27
 
27
- schema_context = schema.context_class.new(query: nil, schema: schema, values: context)
28
-
29
-
30
- @warden = @schema.warden_class.new(
31
- schema: @schema,
32
- context: schema_context,
33
- )
34
-
35
- schema_context.warden = @warden
28
+ dummy_query = @schema.query_class.new(@schema, "{ __typename }", validate: false, context: context)
29
+ @types = dummy_query.types # rubocop:disable Development/ContextIsPassedCop
36
30
  end
37
31
 
38
32
  def document
@@ -44,9 +38,9 @@ module GraphQL
44
38
  def build_schema_node
45
39
  if !schema_respects_root_name_conventions?(@schema)
46
40
  GraphQL::Language::Nodes::SchemaDefinition.new(
47
- query: (q = warden.root_type_for_operation("query")) && q.graphql_name,
48
- mutation: (m = warden.root_type_for_operation("mutation")) && m.graphql_name,
49
- subscription: (s = warden.root_type_for_operation("subscription")) && s.graphql_name,
41
+ query: @types.query_root&.graphql_name,
42
+ mutation: @types.mutation_root&.graphql_name,
43
+ subscription: @types.subscription_root&.graphql_name,
50
44
  directives: definition_directives(@schema, :schema_directives)
51
45
  )
52
46
  else
@@ -57,7 +51,7 @@ module GraphQL
57
51
  end
58
52
 
59
53
  def build_object_type_node(object_type)
60
- ints = warden.interfaces(object_type)
54
+ ints = @types.interfaces(object_type)
61
55
  if ints.any?
62
56
  ints.sort_by!(&:graphql_name)
63
57
  ints.map! { |iface| build_type_name_node(iface) }
@@ -65,8 +59,9 @@ module GraphQL
65
59
 
66
60
  GraphQL::Language::Nodes::ObjectTypeDefinition.new(
67
61
  name: object_type.graphql_name,
62
+ comment: object_type.comment,
68
63
  interfaces: ints,
69
- fields: build_field_nodes(warden.fields(object_type)),
64
+ fields: build_field_nodes(@types.fields(object_type)),
70
65
  description: object_type.description,
71
66
  directives: directives(object_type),
72
67
  )
@@ -75,7 +70,8 @@ module GraphQL
75
70
  def build_field_node(field)
76
71
  GraphQL::Language::Nodes::FieldDefinition.new(
77
72
  name: field.graphql_name,
78
- arguments: build_argument_nodes(warden.arguments(field)),
73
+ comment: field.comment,
74
+ arguments: build_argument_nodes(@types.arguments(field)),
79
75
  type: build_type_name_node(field.type),
80
76
  description: field.description,
81
77
  directives: directives(field),
@@ -85,8 +81,9 @@ module GraphQL
85
81
  def build_union_type_node(union_type)
86
82
  GraphQL::Language::Nodes::UnionTypeDefinition.new(
87
83
  name: union_type.graphql_name,
84
+ comment: union_type.comment,
88
85
  description: union_type.description,
89
- types: warden.possible_types(union_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
86
+ types: @types.possible_types(union_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
90
87
  directives: directives(union_type),
91
88
  )
92
89
  end
@@ -94,9 +91,10 @@ module GraphQL
94
91
  def build_interface_type_node(interface_type)
95
92
  GraphQL::Language::Nodes::InterfaceTypeDefinition.new(
96
93
  name: interface_type.graphql_name,
97
- interfaces: warden.interfaces(interface_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
94
+ comment: interface_type.comment,
95
+ interfaces: @types.interfaces(interface_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
98
96
  description: interface_type.description,
99
- fields: build_field_nodes(warden.fields(interface_type)),
97
+ fields: build_field_nodes(@types.fields(interface_type)),
100
98
  directives: directives(interface_type),
101
99
  )
102
100
  end
@@ -104,7 +102,8 @@ module GraphQL
104
102
  def build_enum_type_node(enum_type)
105
103
  GraphQL::Language::Nodes::EnumTypeDefinition.new(
106
104
  name: enum_type.graphql_name,
107
- values: warden.enum_values(enum_type).sort_by(&:graphql_name).map do |enum_value|
105
+ comment: enum_type.comment,
106
+ values: @types.enum_values(enum_type).sort_by(&:graphql_name).map do |enum_value|
108
107
  build_enum_value_node(enum_value)
109
108
  end,
110
109
  description: enum_type.description,
@@ -115,6 +114,7 @@ module GraphQL
115
114
  def build_enum_value_node(enum_value)
116
115
  GraphQL::Language::Nodes::EnumValueDefinition.new(
117
116
  name: enum_value.graphql_name,
117
+ comment: enum_value.comment,
118
118
  description: enum_value.description,
119
119
  directives: directives(enum_value),
120
120
  )
@@ -123,6 +123,7 @@ module GraphQL
123
123
  def build_scalar_type_node(scalar_type)
124
124
  GraphQL::Language::Nodes::ScalarTypeDefinition.new(
125
125
  name: scalar_type.graphql_name,
126
+ comment: scalar_type.comment,
126
127
  description: scalar_type.description,
127
128
  directives: directives(scalar_type),
128
129
  )
@@ -137,6 +138,7 @@ module GraphQL
137
138
 
138
139
  argument_node = GraphQL::Language::Nodes::InputValueDefinition.new(
139
140
  name: argument.graphql_name,
141
+ comment: argument.comment,
140
142
  description: argument.description,
141
143
  type: build_type_name_node(argument.type),
142
144
  default_value: default_value,
@@ -149,7 +151,8 @@ module GraphQL
149
151
  def build_input_object_node(input_object)
150
152
  GraphQL::Language::Nodes::InputObjectTypeDefinition.new(
151
153
  name: input_object.graphql_name,
152
- fields: build_argument_nodes(warden.arguments(input_object)),
154
+ comment: input_object.comment,
155
+ fields: build_argument_nodes(@types.arguments(input_object)),
153
156
  description: input_object.description,
154
157
  directives: directives(input_object),
155
158
  )
@@ -159,7 +162,7 @@ module GraphQL
159
162
  GraphQL::Language::Nodes::DirectiveDefinition.new(
160
163
  name: directive.graphql_name,
161
164
  repeatable: directive.repeatable?,
162
- arguments: build_argument_nodes(warden.arguments(directive)),
165
+ arguments: build_argument_nodes(@types.arguments(directive)),
163
166
  locations: build_directive_location_nodes(directive.locations),
164
167
  description: directive.description,
165
168
  )
@@ -204,7 +207,7 @@ module GraphQL
204
207
  when "INPUT_OBJECT"
205
208
  GraphQL::Language::Nodes::InputObject.new(
206
209
  arguments: default_value.to_h.map do |arg_name, arg_value|
207
- args = @warden.arguments(type)
210
+ args = @types.arguments(type)
208
211
  arg = args.find { |a| a.keyword.to_s == arg_name.to_s }
209
212
  if arg.nil?
210
213
  raise ArgumentError, "No argument definition on #{type.graphql_name} for argument: #{arg_name.inspect} (expected one of: #{args.map(&:keyword)})"
@@ -260,13 +263,39 @@ module GraphQL
260
263
  end
261
264
 
262
265
  def build_definition_nodes
263
- dirs_to_build = warden.directives
266
+ dirs_to_build = @types.directives
264
267
  if !include_built_in_directives
265
268
  dirs_to_build = dirs_to_build.reject { |directive| directive.default_directive? }
266
269
  end
267
270
  definitions = build_directive_nodes(dirs_to_build)
271
+ all_types = @types.all_types
272
+ type_nodes = build_type_definition_nodes(all_types)
273
+
274
+ if (ex_t = schema.extra_types).any?
275
+ dummy_query = Class.new(GraphQL::Schema::Object) do
276
+ graphql_name "DummyQuery"
277
+ (all_types + ex_t).each_with_index do |type, idx|
278
+ if !type.kind.input_object? && !type.introspection?
279
+ field "f#{idx}", type
280
+ end
281
+ end
282
+ end
283
+
284
+ extra_types_schema = Class.new(GraphQL::Schema) do
285
+ query(dummy_query)
286
+ end
287
+
288
+ extra_types_types = GraphQL::Query.new(extra_types_schema, "{ __typename }", context: @context).types # rubocop:disable Development/ContextIsPassedCop
289
+ # Temporarily replace `@types` with something from this example schema.
290
+ # It'd be much nicer to pass this in, but that would be a big refactor :S
291
+ prev_types = @types
292
+ @types = extra_types_types
293
+ type_nodes += build_type_definition_nodes(ex_t)
294
+ @types = prev_types
295
+ end
296
+
297
+ type_nodes.sort_by!(&:name)
268
298
 
269
- type_nodes = build_type_definition_nodes(warden.reachable_types + schema.extra_types)
270
299
  if @include_one_of
271
300
  # This may have been set to true when iterating over all types
272
301
  definitions.concat(build_directive_nodes([GraphQL::Schema::Directive::OneOf]))
@@ -289,9 +318,7 @@ module GraphQL
289
318
  types = types.reject { |type| type.kind.scalar? && type.default_scalar? }
290
319
  end
291
320
 
292
- types
293
- .map { |type| build_type_definition_node(type) }
294
- .sort_by(&:name)
321
+ types.map { |type| build_type_definition_node(type) }
295
322
  end
296
323
 
297
324
  def build_field_nodes(fields)
@@ -351,7 +378,7 @@ module GraphQL
351
378
  dirs
352
379
  end
353
380
 
354
- attr_reader :schema, :warden, :always_include_schema,
381
+ attr_reader :schema, :always_include_schema,
355
382
  :include_introspection_types, :include_built_in_directives, :include_built_in_scalars
356
383
  end
357
384
  end
@@ -19,7 +19,7 @@ module GraphQL
19
19
  @scanner.eos?
20
20
  end
21
21
 
22
- attr_reader :pos
22
+ attr_reader :pos, :tokens_count
23
23
 
24
24
  def advance
25
25
  @scanner.skip(IGNORE_REGEXP)
@@ -57,20 +57,23 @@ module GraphQL
57
57
  @scanner.skip(IDENTIFIER_REGEXP)
58
58
  :IDENTIFIER
59
59
  when ByteFor::NUMBER
60
- @scanner.skip(NUMERIC_REGEXP)
60
+ if len = @scanner.skip(NUMERIC_REGEXP)
61
61
 
62
- if GraphQL.reject_numbers_followed_by_names
63
- new_pos = @scanner.pos
64
- peek_byte = @string.getbyte(new_pos)
65
- next_first_byte = FIRST_BYTES[peek_byte]
66
- if next_first_byte == ByteFor::NAME || next_first_byte == ByteFor::IDENTIFIER
67
- number_part = token_value
68
- name_part = @scanner.scan(IDENTIFIER_REGEXP)
69
- raise_parse_error("Name after number is not allowed (in `#{number_part}#{name_part}`)")
62
+ if GraphQL.reject_numbers_followed_by_names
63
+ new_pos = @scanner.pos
64
+ peek_byte = @string.getbyte(new_pos)
65
+ next_first_byte = FIRST_BYTES[peek_byte]
66
+ if next_first_byte == ByteFor::NAME || next_first_byte == ByteFor::IDENTIFIER
67
+ number_part = token_value
68
+ name_part = @scanner.scan(IDENTIFIER_REGEXP)
69
+ raise_parse_error("Name after number is not allowed (in `#{number_part}#{name_part}`)")
70
+ end
70
71
  end
72
+ # Check for a matched decimal:
73
+ @scanner[1] ? :FLOAT : :INT
74
+ else
75
+ raise_parse_error("Expected a number, but it was malformed (#{@string[@pos].inspect})")
71
76
  end
72
- # Check for a matched decimal:
73
- @scanner[1] ? :FLOAT : :INT
74
77
  when ByteFor::ELLIPSIS
75
78
  if @string.getbyte(@pos + 1) != 46 || @string.getbyte(@pos + 2) != 46
76
79
  raise_parse_error("Expected `...`, actual: #{@string[@pos..@pos + 2].inspect}")
@@ -345,17 +348,14 @@ module GraphQL
345
348
  def self.tokenize(string)
346
349
  lexer = GraphQL::Language::Lexer.new(string)
347
350
  tokens = []
348
- prev_token = nil
349
351
  while (token_name = lexer.advance)
350
352
  new_token = [
351
353
  token_name,
352
354
  lexer.line_number,
353
355
  lexer.column_number,
354
356
  lexer.debug_token_value(token_name),
355
- prev_token,
356
357
  ]
357
358
  tokens << new_token
358
- prev_token = new_token
359
359
  end
360
360
  tokens
361
361
  end
@@ -34,11 +34,11 @@ module GraphQL
34
34
  attr_reader :filename
35
35
 
36
36
  def line
37
- @line ||= @source.line_at(@pos)
37
+ @line ||= @source&.line_at(@pos)
38
38
  end
39
39
 
40
40
  def col
41
- @col ||= @source.column_at(@pos)
41
+ @col ||= @source&.column_at(@pos)
42
42
  end
43
43
 
44
44
  def definition_line
@@ -270,15 +270,17 @@ module GraphQL
270
270
  "col: nil",
271
271
  "pos: nil",
272
272
  "filename: nil",
273
- "source: nil",
273
+ "source: nil"
274
274
  ]
275
275
 
276
+ IGNORED_MARSHALLING_KEYWORDS = [:comment]
277
+
276
278
  def generate_initialize
277
279
  return if method_defined?(:marshal_load, false) # checking for `:initialize` doesn't work right
278
280
 
279
281
  scalar_method_names = @scalar_methods
280
282
  # TODO: These probably should be scalar methods, but `types` returns an array
281
- [:types, :description].each do |extra_method|
283
+ [:types, :description, :comment].each do |extra_method|
282
284
  if method_defined?(extra_method)
283
285
  scalar_method_names += [extra_method]
284
286
  end
@@ -307,6 +309,12 @@ module GraphQL
307
309
  keywords = scalar_method_names.map { |m| "#{m}: #{m}"} +
308
310
  children_method_names.map { |m| "#{m}: #{m}" }
309
311
 
312
+ ignored_keywords = IGNORED_MARSHALLING_KEYWORDS.map do |keyword|
313
+ "#{keyword.to_s}: nil"
314
+ end
315
+
316
+ marshalling_method_names = all_method_names - IGNORED_MARSHALLING_KEYWORDS
317
+
310
318
  module_eval <<-RUBY, __FILE__, __LINE__
311
319
  def initialize(#{arguments.join(", ")})
312
320
  @line = line
@@ -317,7 +325,7 @@ module GraphQL
317
325
  #{assignments.join("\n")}
318
326
  end
319
327
 
320
- def self.from_a(filename, line, col, #{all_method_names.join(", ")})
328
+ def self.from_a(filename, line, col, #{marshalling_method_names.join(", ")}, #{ignored_keywords.join(", ")})
321
329
  self.new(filename: filename, line: line, col: col, #{keywords.join(", ")})
322
330
  end
323
331
 
@@ -325,12 +333,12 @@ module GraphQL
325
333
  [
326
334
  line, col, # use methods here to force them to be calculated
327
335
  @filename,
328
- #{all_method_names.map { |n| "@#{n}," }.join}
336
+ #{marshalling_method_names.map { |n| "@#{n}," }.join}
329
337
  ]
330
338
  end
331
339
 
332
340
  def marshal_load(values)
333
- @line, @col, @filename #{all_method_names.map { |n| ", @#{n}"}.join} = values
341
+ @line, @col, @filename #{marshalling_method_names.map { |n| ", @#{n}"}.join} = values
334
342
  end
335
343
  RUBY
336
344
  end
@@ -635,7 +643,7 @@ module GraphQL
635
643
  end
636
644
 
637
645
  class ScalarTypeDefinition < AbstractNode
638
- attr_reader :description
646
+ attr_reader :description, :comment
639
647
  scalar_methods :name
640
648
  children_methods({
641
649
  directives: GraphQL::Language::Nodes::Directive,
@@ -652,7 +660,7 @@ module GraphQL
652
660
  end
653
661
 
654
662
  class InputValueDefinition < AbstractNode
655
- attr_reader :description
663
+ attr_reader :description, :comment
656
664
  scalar_methods :name, :type, :default_value
657
665
  children_methods({
658
666
  directives: GraphQL::Language::Nodes::Directive,
@@ -661,7 +669,7 @@ module GraphQL
661
669
  end
662
670
 
663
671
  class FieldDefinition < AbstractNode
664
- attr_reader :description
672
+ attr_reader :description, :comment
665
673
  scalar_methods :name, :type
666
674
  children_methods({
667
675
  arguments: GraphQL::Language::Nodes::InputValueDefinition,
@@ -681,7 +689,7 @@ module GraphQL
681
689
  end
682
690
 
683
691
  class ObjectTypeDefinition < AbstractNode
684
- attr_reader :description
692
+ attr_reader :description, :comment
685
693
  scalar_methods :name, :interfaces
686
694
  children_methods({
687
695
  directives: GraphQL::Language::Nodes::Directive,
@@ -700,7 +708,7 @@ module GraphQL
700
708
  end
701
709
 
702
710
  class InterfaceTypeDefinition < AbstractNode
703
- attr_reader :description
711
+ attr_reader :description, :comment
704
712
  scalar_methods :name
705
713
  children_methods({
706
714
  interfaces: GraphQL::Language::Nodes::TypeName,
@@ -721,7 +729,7 @@ module GraphQL
721
729
  end
722
730
 
723
731
  class UnionTypeDefinition < AbstractNode
724
- attr_reader :description, :types
732
+ attr_reader :description, :comment, :types
725
733
  scalar_methods :name
726
734
  children_methods({
727
735
  directives: GraphQL::Language::Nodes::Directive,
@@ -739,7 +747,7 @@ module GraphQL
739
747
  end
740
748
 
741
749
  class EnumValueDefinition < AbstractNode
742
- attr_reader :description
750
+ attr_reader :description, :comment
743
751
  scalar_methods :name
744
752
  children_methods({
745
753
  directives: GraphQL::Language::Nodes::Directive,
@@ -748,7 +756,7 @@ module GraphQL
748
756
  end
749
757
 
750
758
  class EnumTypeDefinition < AbstractNode
751
- attr_reader :description
759
+ attr_reader :description, :comment
752
760
  scalar_methods :name
753
761
  children_methods({
754
762
  directives: GraphQL::Language::Nodes::Directive,
@@ -767,7 +775,7 @@ module GraphQL
767
775
  end
768
776
 
769
777
  class InputObjectTypeDefinition < AbstractNode
770
- attr_reader :description
778
+ attr_reader :description, :comment
771
779
  scalar_methods :name
772
780
  children_methods({
773
781
  directives: GraphQL::Language::Nodes::Directive,
@@ -49,6 +49,11 @@ module GraphQL
49
49
  end
50
50
  end
51
51
 
52
+ def tokens_count
53
+ parse
54
+ @lexer.tokens_count
55
+ end
56
+
52
57
  def line_at(pos)
53
58
  line = lines_at.bsearch_index { |l| l >= pos }
54
59
  if line.nil?
@@ -141,7 +146,12 @@ module GraphQL
141
146
  parse_operation_type
142
147
  end
143
148
 
144
- op_name = at?(:IDENTIFIER) ? parse_name : nil
149
+ op_name = case token_name
150
+ when :LPAREN, :LCURLY, :DIR_SIGN
151
+ nil
152
+ else
153
+ parse_name
154
+ end
145
155
 
146
156
  variable_definitions = if at?(:LPAREN)
147
157
  expect_token(:LPAREN)
@@ -398,6 +408,9 @@ module GraphQL
398
408
  def parse_union_members
399
409
  if at?(:EQUALS)
400
410
  expect_token :EQUALS
411
+ if at?(:PIPE)
412
+ advance_token
413
+ end
401
414
  list = [parse_type_name]
402
415
  while at?(:PIPE)
403
416
  advance_token