graphql 2.3.7 → 2.4.5

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.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (125) 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 +8 -7
  9. data/lib/graphql/analysis.rb +4 -4
  10. data/lib/graphql/autoload.rb +37 -0
  11. data/lib/graphql/current.rb +52 -0
  12. data/lib/graphql/dataloader/async_dataloader.rb +7 -6
  13. data/lib/graphql/dataloader/source.rb +7 -4
  14. data/lib/graphql/dataloader.rb +40 -19
  15. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
  16. data/lib/graphql/execution/interpreter/resolve.rb +13 -9
  17. data/lib/graphql/execution/interpreter/runtime.rb +35 -31
  18. data/lib/graphql/execution/interpreter.rb +6 -4
  19. data/lib/graphql/execution/lookahead.rb +18 -11
  20. data/lib/graphql/introspection/directive_type.rb +1 -1
  21. data/lib/graphql/introspection/entry_points.rb +2 -2
  22. data/lib/graphql/introspection/field_type.rb +1 -1
  23. data/lib/graphql/introspection/schema_type.rb +6 -11
  24. data/lib/graphql/introspection/type_type.rb +5 -5
  25. data/lib/graphql/invalid_null_error.rb +1 -1
  26. data/lib/graphql/language/cache.rb +13 -0
  27. data/lib/graphql/language/comment.rb +18 -0
  28. data/lib/graphql/language/document_from_schema_definition.rb +62 -34
  29. data/lib/graphql/language/lexer.rb +18 -15
  30. data/lib/graphql/language/nodes.rb +24 -16
  31. data/lib/graphql/language/parser.rb +14 -1
  32. data/lib/graphql/language/printer.rb +31 -15
  33. data/lib/graphql/language/sanitized_printer.rb +1 -1
  34. data/lib/graphql/language.rb +6 -6
  35. data/lib/graphql/pagination/connection.rb +1 -1
  36. data/lib/graphql/query/context/scoped_context.rb +1 -1
  37. data/lib/graphql/query/context.rb +13 -6
  38. data/lib/graphql/query/null_context.rb +3 -5
  39. data/lib/graphql/query/variable_validation_error.rb +1 -1
  40. data/lib/graphql/query.rb +72 -18
  41. data/lib/graphql/railtie.rb +7 -0
  42. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  43. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  44. data/lib/graphql/rubocop.rb +2 -0
  45. data/lib/graphql/schema/addition.rb +2 -1
  46. data/lib/graphql/schema/always_visible.rb +6 -2
  47. data/lib/graphql/schema/argument.rb +14 -1
  48. data/lib/graphql/schema/build_from_definition.rb +9 -1
  49. data/lib/graphql/schema/directive/flagged.rb +2 -2
  50. data/lib/graphql/schema/directive.rb +1 -1
  51. data/lib/graphql/schema/enum.rb +71 -23
  52. data/lib/graphql/schema/enum_value.rb +10 -2
  53. data/lib/graphql/schema/field/connection_extension.rb +1 -1
  54. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  55. data/lib/graphql/schema/field.rb +102 -47
  56. data/lib/graphql/schema/field_extension.rb +1 -1
  57. data/lib/graphql/schema/has_single_input_argument.rb +5 -2
  58. data/lib/graphql/schema/input_object.rb +90 -39
  59. data/lib/graphql/schema/interface.rb +22 -5
  60. data/lib/graphql/schema/introspection_system.rb +5 -16
  61. data/lib/graphql/schema/loader.rb +1 -1
  62. data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
  63. data/lib/graphql/schema/member/has_arguments.rb +25 -20
  64. data/lib/graphql/schema/member/has_directives.rb +3 -3
  65. data/lib/graphql/schema/member/has_fields.rb +26 -6
  66. data/lib/graphql/schema/member/has_interfaces.rb +4 -4
  67. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  68. data/lib/graphql/schema/member/has_validators.rb +1 -1
  69. data/lib/graphql/schema/object.rb +8 -0
  70. data/lib/graphql/schema/printer.rb +1 -0
  71. data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
  72. data/lib/graphql/schema/resolver.rb +12 -14
  73. data/lib/graphql/schema/subscription.rb +2 -2
  74. data/lib/graphql/schema/type_expression.rb +2 -2
  75. data/lib/graphql/schema/union.rb +1 -1
  76. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  77. data/lib/graphql/schema/validator/required_validator.rb +28 -4
  78. data/lib/graphql/schema/validator.rb +3 -1
  79. data/lib/graphql/schema/visibility/migration.rb +187 -0
  80. data/lib/graphql/schema/visibility/profile.rb +353 -0
  81. data/lib/graphql/schema/visibility/visit.rb +190 -0
  82. data/lib/graphql/schema/visibility.rb +294 -0
  83. data/lib/graphql/schema/warden.rb +166 -16
  84. data/lib/graphql/schema.rb +348 -94
  85. data/lib/graphql/static_validation/base_visitor.rb +6 -5
  86. data/lib/graphql/static_validation/literal_validator.rb +4 -4
  87. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  88. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  89. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
  90. data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -3
  91. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
  92. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  93. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +2 -2
  94. data/lib/graphql/static_validation/rules/fields_will_merge.rb +8 -7
  95. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  96. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
  97. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  98. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  99. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  100. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  101. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -4
  102. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  103. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  104. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  105. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  106. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  107. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  108. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  109. data/lib/graphql/static_validation/validation_context.rb +18 -2
  110. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +3 -2
  111. data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
  112. data/lib/graphql/subscriptions/event.rb +1 -1
  113. data/lib/graphql/subscriptions.rb +6 -4
  114. data/lib/graphql/testing/helpers.rb +10 -6
  115. data/lib/graphql/tracing/notifications_trace.rb +2 -2
  116. data/lib/graphql/types/relay/connection_behaviors.rb +12 -2
  117. data/lib/graphql/types/relay/edge_behaviors.rb +11 -1
  118. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  119. data/lib/graphql/types.rb +18 -11
  120. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  121. data/lib/graphql/version.rb +1 -1
  122. data/lib/graphql.rb +81 -45
  123. metadata +31 -8
  124. data/lib/graphql/language/token.rb +0 -34
  125. data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -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,16 +51,17 @@ module GraphQL
57
51
  end
58
52
 
59
53
  def build_object_type_node(object_type)
60
- ints = warden.interfaces(object_type)
61
- if ints.any?
54
+ ints = @types.interfaces(object_type)
55
+ if !ints.empty?
62
56
  ints.sort_by!(&:graphql_name)
63
57
  ints.map! { |iface| build_type_name_node(iface) }
64
58
  end
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)})"
@@ -244,7 +247,7 @@ module GraphQL
244
247
  end
245
248
 
246
249
  def build_argument_nodes(arguments)
247
- if arguments.any?
250
+ if !arguments.empty?
248
251
  nodes = arguments.map { |arg| build_argument_node(arg) }
249
252
  nodes.sort_by!(&:name)
250
253
  nodes
@@ -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).empty?
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)
@@ -319,10 +346,11 @@ module GraphQL
319
346
  end
320
347
 
321
348
  def definition_directives(member, directives_method)
322
- dirs = if !member.respond_to?(directives_method) || member.directives.empty?
349
+ if !member.respond_to?(directives_method) || member.directives.empty?
323
350
  EmptyObjects::EMPTY_ARRAY
324
351
  else
325
- member.public_send(directives_method).map do |dir|
352
+ visible_directives = member.public_send(directives_method).select { |dir| @types.directive_exists?(dir.graphql_name) }
353
+ visible_directives.map! do |dir|
326
354
  args = []
327
355
  dir.arguments.argument_values.each_value do |arg_value| # rubocop:disable Development/ContextIsPassedCop -- directive instance method
328
356
  arg_defn = arg_value.definition
@@ -346,12 +374,12 @@ module GraphQL
346
374
  arguments: args
347
375
  )
348
376
  end
349
- end
350
377
 
351
- dirs
378
+ visible_directives
379
+ end
352
380
  end
353
381
 
354
- attr_reader :schema, :warden, :always_include_schema,
382
+ attr_reader :schema, :always_include_schema,
355
383
  :include_introspection_types, :include_built_in_directives, :include_built_in_scalars
356
384
  end
357
385
  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,26 @@ 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
+ # Attempt to find the part after the `-`
76
+ value = @scanner.scan(/-\s?[a-z0-9]*/i)
77
+ invalid_byte_for_number_error_message = "Expected type 'number', but it was malformed#{value.nil? ? "" : ": #{value.inspect}"}."
78
+ raise_parse_error(invalid_byte_for_number_error_message)
71
79
  end
72
- # Check for a matched decimal:
73
- @scanner[1] ? :FLOAT : :INT
74
80
  when ByteFor::ELLIPSIS
75
81
  if @string.getbyte(@pos + 1) != 46 || @string.getbyte(@pos + 2) != 46
76
82
  raise_parse_error("Expected `...`, actual: #{@string[@pos..@pos + 2].inspect}")
@@ -345,17 +351,14 @@ module GraphQL
345
351
  def self.tokenize(string)
346
352
  lexer = GraphQL::Language::Lexer.new(string)
347
353
  tokens = []
348
- prev_token = nil
349
354
  while (token_name = lexer.advance)
350
355
  new_token = [
351
356
  token_name,
352
357
  lexer.line_number,
353
358
  lexer.column_number,
354
359
  lexer.debug_token_value(token_name),
355
- prev_token,
356
360
  ]
357
361
  tokens << new_token
358
- prev_token = new_token
359
362
  end
360
363
  tokens
361
364
  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
@@ -92,7 +92,7 @@ module GraphQL
92
92
  print_string("@")
93
93
  print_string(directive.name)
94
94
 
95
- if directive.arguments.any?
95
+ if !directive.arguments.empty?
96
96
  print_string("(")
97
97
  directive.arguments.each_with_index do |a, i|
98
98
  print_argument(a)
@@ -117,7 +117,7 @@ module GraphQL
117
117
  print_string(": ")
118
118
  end
119
119
  print_string(field.name)
120
- if field.arguments.any?
120
+ if !field.arguments.empty?
121
121
  print_string("(")
122
122
  field.arguments.each_with_index do |a, i|
123
123
  print_argument(a)
@@ -182,7 +182,7 @@ module GraphQL
182
182
  print_string(operation_definition.name)
183
183
  end
184
184
 
185
- if operation_definition.variables.any?
185
+ if !operation_definition.variables.empty?
186
186
  print_string("(")
187
187
  operation_definition.variables.each_with_index do |v, i|
188
188
  print_variable_definition(v)
@@ -230,7 +230,7 @@ module GraphQL
230
230
 
231
231
  extension ? print_string("extend schema") : print_string("schema")
232
232
 
233
- if schema.directives.any?
233
+ if !schema.directives.empty?
234
234
  schema.directives.each do |dir|
235
235
  print_string("\n ")
236
236
  print_node(dir)
@@ -255,14 +255,14 @@ module GraphQL
255
255
 
256
256
 
257
257
  def print_scalar_type_definition(scalar_type, extension: false)
258
- extension ? print_string("extend ") : print_description(scalar_type)
258
+ extension ? print_string("extend ") : print_description_and_comment(scalar_type)
259
259
  print_string("scalar ")
260
260
  print_string(scalar_type.name)
261
261
  print_directives(scalar_type.directives)
262
262
  end
263
263
 
264
264
  def print_object_type_definition(object_type, extension: false)
265
- extension ? print_string("extend ") : print_description(object_type)
265
+ extension ? print_string("extend ") : print_description_and_comment(object_type)
266
266
  print_string("type ")
267
267
  print_string(object_type.name)
268
268
  print_implements(object_type) unless object_type.interfaces.empty?
@@ -294,7 +294,7 @@ module GraphQL
294
294
  end
295
295
 
296
296
  def print_arguments(arguments, indent: "")
297
- if arguments.all? { |arg| !arg.description }
297
+ if arguments.all? { |arg| !arg.description && !arg.comment }
298
298
  print_string("(")
299
299
  arguments.each_with_index do |arg, i|
300
300
  print_input_value_definition(arg)
@@ -306,6 +306,7 @@ module GraphQL
306
306
 
307
307
  print_string("(\n")
308
308
  arguments.each_with_index do |arg, i|
309
+ print_comment(arg, indent: " " + indent, first_in_block: i == 0)
309
310
  print_description(arg, indent: " " + indent, first_in_block: i == 0)
310
311
  print_string(" ")
311
312
  print_string(indent)
@@ -328,20 +329,20 @@ module GraphQL
328
329
  end
329
330
 
330
331
  def print_interface_type_definition(interface_type, extension: false)
331
- extension ? print_string("extend ") : print_description(interface_type)
332
+ extension ? print_string("extend ") : print_description_and_comment(interface_type)
332
333
  print_string("interface ")
333
334
  print_string(interface_type.name)
334
- print_implements(interface_type) if interface_type.interfaces.any?
335
+ print_implements(interface_type) if !interface_type.interfaces.empty?
335
336
  print_directives(interface_type.directives)
336
337
  print_field_definitions(interface_type.fields)
337
338
  end
338
339
 
339
340
  def print_union_type_definition(union_type, extension: false)
340
- extension ? print_string("extend ") : print_description(union_type)
341
+ extension ? print_string("extend ") : print_description_and_comment(union_type)
341
342
  print_string("union ")
342
343
  print_string(union_type.name)
343
344
  print_directives(union_type.directives)
344
- if union_type.types.any?
345
+ if !union_type.types.empty?
345
346
  print_string(" = ")
346
347
  i = 0
347
348
  union_type.types.each do |t|
@@ -355,14 +356,15 @@ module GraphQL
355
356
  end
356
357
 
357
358
  def print_enum_type_definition(enum_type, extension: false)
358
- extension ? print_string("extend ") : print_description(enum_type)
359
+ extension ? print_string("extend ") : print_description_and_comment(enum_type)
359
360
  print_string("enum ")
360
361
  print_string(enum_type.name)
361
362
  print_directives(enum_type.directives)
362
- if enum_type.values.any?
363
+ if !enum_type.values.empty?
363
364
  print_string(" {\n")
364
365
  enum_type.values.each.with_index do |value, i|
365
366
  print_description(value, indent: " ", first_in_block: i == 0)
367
+ print_comment(value, indent: " ", first_in_block: i == 0)
366
368
  print_enum_value_definition(value)
367
369
  end
368
370
  print_string("}")
@@ -377,7 +379,7 @@ module GraphQL
377
379
  end
378
380
 
379
381
  def print_input_object_type_definition(input_object_type, extension: false)
380
- extension ? print_string("extend ") : print_description(input_object_type)
382
+ extension ? print_string("extend ") : print_description_and_comment(input_object_type)
381
383
  print_string("input ")
382
384
  print_string(input_object_type.name)
383
385
  print_directives(input_object_type.directives)
@@ -385,6 +387,7 @@ module GraphQL
385
387
  print_string(" {\n")
386
388
  input_object_type.fields.each.with_index do |field, i|
387
389
  print_description(field, indent: " ", first_in_block: i == 0)
390
+ print_comment(field, indent: " ", first_in_block: i == 0)
388
391
  print_string(" ")
389
392
  print_input_value_definition(field)
390
393
  print_string("\n")
@@ -398,7 +401,7 @@ module GraphQL
398
401
  print_string("directive @")
399
402
  print_string(directive.name)
400
403
 
401
- if directive.arguments.any?
404
+ if !directive.arguments.empty?
402
405
  print_arguments(directive.arguments)
403
406
  end
404
407
 
@@ -424,6 +427,18 @@ module GraphQL
424
427
  print_string(GraphQL::Language::BlockString.print(node.description, indent: indent))
425
428
  end
426
429
 
430
+ def print_comment(node, indent: "", first_in_block: true)
431
+ return unless node.comment
432
+
433
+ print_string("\n") if indent != "" && !first_in_block
434
+ print_string(GraphQL::Language::Comment.print(node.comment, indent: indent))
435
+ end
436
+
437
+ def print_description_and_comment(node)
438
+ print_description(node)
439
+ print_comment(node)
440
+ end
441
+
427
442
  def print_field_definitions(fields)
428
443
  return if fields.empty?
429
444
 
@@ -431,6 +446,7 @@ module GraphQL
431
446
  i = 0
432
447
  fields.each do |field|
433
448
  print_description(field, indent: " ", first_in_block: i == 0)
449
+ print_comment(field, indent: " ", first_in_block: i == 0)
434
450
  print_string(" ")
435
451
  print_field_definition(field)
436
452
  print_string("\n")
@@ -113,7 +113,7 @@ module GraphQL
113
113
  end
114
114
 
115
115
  def print_field(field, indent: "")
116
- @current_field = query.get_field(@current_type, field.name)
116
+ @current_field = query.types.field(@current_type, field.name)
117
117
  old_type = @current_type
118
118
  @current_type = @current_field.type.unwrap
119
119
  super