graphql 2.0.19 → 2.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/backtrace/trace.rb +96 -0
  3. data/lib/graphql/backtrace.rb +6 -1
  4. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  5. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
  6. data/lib/graphql/execution/interpreter/runtime.rb +206 -171
  7. data/lib/graphql/execution/interpreter.rb +1 -1
  8. data/lib/graphql/filter.rb +7 -2
  9. data/lib/graphql/language/document_from_schema_definition.rb +25 -9
  10. data/lib/graphql/language/nodes.rb +25 -7
  11. data/lib/graphql/language/parser.rb +476 -459
  12. data/lib/graphql/language/parser.y +6 -2
  13. data/lib/graphql/pagination/connection.rb +5 -5
  14. data/lib/graphql/query/context.rb +13 -12
  15. data/lib/graphql/query/null_context.rb +1 -1
  16. data/lib/graphql/query.rb +9 -5
  17. data/lib/graphql/schema/argument.rb +7 -9
  18. data/lib/graphql/schema/build_from_definition.rb +15 -3
  19. data/lib/graphql/schema/enum_value.rb +2 -5
  20. data/lib/graphql/schema/field.rb +16 -13
  21. data/lib/graphql/schema/field_extension.rb +1 -4
  22. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  23. data/lib/graphql/schema/member/base_dsl_methods.rb +13 -11
  24. data/lib/graphql/schema/member/has_arguments.rb +1 -1
  25. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  26. data/lib/graphql/schema/member/has_directives.rb +15 -10
  27. data/lib/graphql/schema/member/has_fields.rb +81 -36
  28. data/lib/graphql/schema/member/has_validators.rb +2 -2
  29. data/lib/graphql/schema/member/relay_shortcuts.rb +19 -0
  30. data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
  31. data/lib/graphql/schema/resolver.rb +4 -4
  32. data/lib/graphql/schema/validator.rb +1 -1
  33. data/lib/graphql/schema/warden.rb +3 -1
  34. data/lib/graphql/schema.rb +41 -16
  35. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  36. data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
  37. data/lib/graphql/tracing/appsignal_trace.rb +13 -2
  38. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  39. data/lib/graphql/tracing/notifications_trace.rb +2 -1
  40. data/lib/graphql/tracing/platform_trace.rb +21 -19
  41. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
  42. data/lib/graphql/tracing/trace.rb +75 -0
  43. data/lib/graphql/tracing.rb +3 -123
  44. data/lib/graphql/types/relay/connection_behaviors.rb +24 -2
  45. data/lib/graphql/types/relay/edge_behaviors.rb +16 -2
  46. data/lib/graphql/types/relay/node_behaviors.rb +7 -1
  47. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  48. data/lib/graphql/types/relay.rb +0 -1
  49. data/lib/graphql/version.rb +1 -1
  50. data/lib/graphql.rb +11 -7
  51. metadata +5 -4
  52. data/lib/graphql/language/lexer.ri +0 -744
  53. data/lib/graphql/types/relay/default_relay.rb +0 -27
@@ -284,7 +284,11 @@ rule
284
284
  | directive_definition
285
285
 
286
286
  schema_definition:
287
- SCHEMA directives_list_opt LCURLY operation_type_definition_list RCURLY { result = make_node(:SchemaDefinition, position_source: val[0], definition_line: val[0][1], directives: val[1], **val[3]) }
287
+ SCHEMA directives_list_opt operation_type_definition_list_opt { result = make_node(:SchemaDefinition, position_source: val[0], definition_line: val[0][1], directives: val[1], **val[2]) }
288
+
289
+ operation_type_definition_list_opt:
290
+ /* none */ { result = {} }
291
+ | LCURLY operation_type_definition_list RCURLY { result = val[1] }
288
292
 
289
293
  operation_type_definition_list:
290
294
  operation_type_definition
@@ -460,7 +464,7 @@ def parse_document
460
464
  @document ||= begin
461
465
  # Break the string into tokens
462
466
  @trace.lex(query_string: @query_string) do
463
- @tokens ||= GraphQL.scan(@query_string)
467
+ @tokens ||= GraphQL::Language::Lexer.tokenize(@query_string)
464
468
  end
465
469
  # From the tokens, build an AST
466
470
  @trace.parse(query_string: @query_string) do
@@ -58,7 +58,7 @@ module GraphQL
58
58
  # @param arguments [Hash] The arguments to the field that returned the collection wrapped by this connection
59
59
  # @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given and no `default_page_size` is set.
60
60
  # @param default_page_size [Integer, nil] A configured value to determine the result size when neither first or last are given.
61
- def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: :not_given, default_page_size: :not_given, last: nil, before: nil, edge_class: nil, arguments: nil)
61
+ def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, last: nil, before: nil, edge_class: nil, arguments: nil)
62
62
  @items = items
63
63
  @parent = parent
64
64
  @context = context
@@ -71,14 +71,14 @@ module GraphQL
71
71
  @edge_class = edge_class || self.class::Edge
72
72
  # This is only true if the object was _initialized_ with an override
73
73
  # or if one is assigned later.
74
- @has_max_page_size_override = max_page_size != :not_given
75
- @max_page_size = if max_page_size == :not_given
74
+ @has_max_page_size_override = max_page_size != NOT_CONFIGURED
75
+ @max_page_size = if max_page_size == NOT_CONFIGURED
76
76
  nil
77
77
  else
78
78
  max_page_size
79
79
  end
80
- @has_default_page_size_override = default_page_size != :not_given
81
- @default_page_size = if default_page_size == :not_given
80
+ @has_default_page_size_override = default_page_size != NOT_CONFIGURED
81
+ @default_page_size = if default_page_size == NOT_CONFIGURED
82
82
  nil
83
83
  else
84
84
  default_page_size
@@ -91,8 +91,8 @@ module GraphQL
91
91
  end
92
92
 
93
93
  class ScopedContext
94
- NO_PATH = [].freeze
95
- NO_CONTEXT = {}.freeze
94
+ NO_PATH = GraphQL::EmptyObjects::EMPTY_ARRAY
95
+ NO_CONTEXT = GraphQL::EmptyObjects::EMPTY_HASH
96
96
 
97
97
  def initialize(query_context)
98
98
  @query_context = query_context
@@ -226,8 +226,8 @@ module GraphQL
226
226
  if key == :current_path
227
227
  current_path
228
228
  else
229
- thread_info = Thread.current[:__graphql_runtime_info]
230
- thread_info && thread_info[key]
229
+ (current_runtime_state = Thread.current[:__graphql_runtime_info]) &&
230
+ (current_runtime_state.public_send(key))
231
231
  end
232
232
  else
233
233
  # not found
@@ -236,11 +236,11 @@ module GraphQL
236
236
  end
237
237
 
238
238
  def current_path
239
- thread_info = Thread.current[:__graphql_runtime_info]
240
- path = thread_info &&
241
- (result = thread_info[:current_result]) &&
239
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
240
+ path = current_runtime_state &&
241
+ (result = current_runtime_state.current_result) &&
242
242
  (result.path)
243
- if path && (rn = thread_info[:current_result_name])
243
+ if path && (rn = current_runtime_state.current_result_name)
244
244
  path = path.dup
245
245
  path.push(rn)
246
246
  end
@@ -259,8 +259,8 @@ module GraphQL
259
259
 
260
260
  def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
261
261
  if RUNTIME_METADATA_KEYS.include?(key)
262
- (thread_info = Thread.current[:__graphql_runtime_info]) &&
263
- thread_info[key]
262
+ (runtime = Thread.current[:__graphql_runtime_info]) &&
263
+ (runtime.public_send(key))
264
264
  elsif @scoped_context.key?(key)
265
265
  scoped_context[key]
266
266
  elsif @provided_values.key?(key)
@@ -276,8 +276,9 @@ module GraphQL
276
276
 
277
277
  def dig(key, *other_keys)
278
278
  if RUNTIME_METADATA_KEYS.include?(key)
279
- (thread_info = Thread.current[:__graphql_runtime_info]).key?(key) &&
280
- thread_info.dig(key, *other_keys)
279
+ (current_runtime_state = Thread.current[:__graphql_runtime_info]) &&
280
+ (obj = current_runtime_state.public_send(key)) &&
281
+ obj.dig(*other_keys)
281
282
  elsif @scoped_context.key?(key)
282
283
  @scoped_context.dig(key, *other_keys)
283
284
  else
@@ -24,7 +24,7 @@ module GraphQL
24
24
  @dataloader = GraphQL::Dataloader::NullDataloader.new
25
25
  @schema = NullSchema
26
26
  @warden = NullWarden.new(
27
- GraphQL::Filter.new,
27
+ GraphQL::Filter.new(silence_deprecation_warning: true),
28
28
  context: self,
29
29
  schema: @schema,
30
30
  )
data/lib/graphql/query.rb CHANGED
@@ -100,12 +100,16 @@ module GraphQL
100
100
 
101
101
  # Support `ctx[:backtrace] = true` for wrapping backtraces
102
102
  if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
103
- context_tracers += [GraphQL::Backtrace::Tracer]
104
- @tracers << GraphQL::Backtrace::Tracer
103
+ if schema.trace_class <= GraphQL::Tracing::LegacyTrace
104
+ context_tracers += [GraphQL::Backtrace::Tracer]
105
+ @tracers << GraphQL::Backtrace::Tracer
106
+ elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
107
+ raise "Invariant: `backtrace: true` should have provided a trace class with Backtrace mixed in, but it didnt. (Found: #{current_trace.class.ancestors}). This is a bug in GraphQL-Ruby, please report it on GitHub."
108
+ end
105
109
  end
106
110
 
107
111
  if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::LegacyTrace)
108
- raise ArgumentError, "context[:tracers] and context[:backtrace] are not supported without `tracer_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
112
+ raise ArgumentError, "context[:tracers] are not supported without `trace_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
109
113
  end
110
114
 
111
115
 
@@ -318,8 +322,8 @@ module GraphQL
318
322
  # @param value [Object] Any runtime value
319
323
  # @return [GraphQL::ObjectType, nil] The runtime type of `value` from {Schema#resolve_type}
320
324
  # @see {#possible_types} to apply filtering from `only` / `except`
321
- def resolve_type(abstract_type, value = :__undefined__)
322
- if value.is_a?(Symbol) && value == :__undefined__
325
+ def resolve_type(abstract_type, value = NOT_CONFIGURED)
326
+ if value.is_a?(Symbol) && value == NOT_CONFIGURED
323
327
  # Old method signature
324
328
  value = abstract_type
325
329
  abstract_type = nil
@@ -7,9 +7,7 @@ module GraphQL
7
7
  include GraphQL::Schema::Member::HasDirectives
8
8
  include GraphQL::Schema::Member::HasDeprecationReason
9
9
  include GraphQL::Schema::Member::HasValidators
10
- include GraphQL::Schema::FindInheritedValue::EmptyObjects
11
-
12
- NO_DEFAULT = :__no_default__
10
+ include GraphQL::EmptyObjects
13
11
 
14
12
  # @return [String] the GraphQL name for this argument, camelized unless `camelize: false` is provided
15
13
  attr_reader :name
@@ -20,8 +18,8 @@ module GraphQL
20
18
 
21
19
  # @param new_prepare [Method, Proc]
22
20
  # @return [Symbol] A method or proc to call to transform this value before sending it to field resolution method
23
- def prepare(new_prepare = NO_DEFAULT)
24
- if new_prepare != NO_DEFAULT
21
+ def prepare(new_prepare = NOT_CONFIGURED)
22
+ if new_prepare != NOT_CONFIGURED
25
23
  @prepare = new_prepare
26
24
  end
27
25
  @prepare
@@ -52,7 +50,7 @@ module GraphQL
52
50
  # @param deprecation_reason [String]
53
51
  # @param validates [Hash, nil] Options for building validators, if any should be applied
54
52
  # @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
55
- def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
53
+ def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
56
54
  arg_name ||= name
57
55
  @name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
58
56
  @type_expr = type_expr || type
@@ -104,8 +102,8 @@ module GraphQL
104
102
 
105
103
  # @param default_value [Object] The value to use when the client doesn't provide one
106
104
  # @return [Object] the value used when the client doesn't provide a value for this argument
107
- def default_value(new_default_value = NO_DEFAULT)
108
- if new_default_value != NO_DEFAULT
105
+ def default_value(new_default_value = NOT_CONFIGURED)
106
+ if new_default_value != NOT_CONFIGURED
109
107
  @default_value = new_default_value
110
108
  end
111
109
  @default_value
@@ -113,7 +111,7 @@ module GraphQL
113
111
 
114
112
  # @return [Boolean] True if this argument has a default value
115
113
  def default_value?
116
- @default_value != NO_DEFAULT
114
+ @default_value != NOT_CONFIGURED
117
115
  end
118
116
 
119
117
  def replace_null_with_default?
@@ -21,6 +21,7 @@ module GraphQL
21
21
 
22
22
  # @api private
23
23
  module Builder
24
+ include GraphQL::EmptyObjects
24
25
  extend self
25
26
 
26
27
  def build(schema_superclass, document, default_resolve:, using: {}, relay:)
@@ -99,6 +100,16 @@ module GraphQL
99
100
  raise InvalidDocumentError.new("Specified subscription type \"#{schema_definition.subscription}\" not found in document.") unless types[schema_definition.subscription]
100
101
  subscription_root_type = types[schema_definition.subscription]
101
102
  end
103
+
104
+ if schema_definition.query.nil? &&
105
+ schema_definition.mutation.nil? &&
106
+ schema_definition.subscription.nil?
107
+ # This schema may have been given with directives only,
108
+ # check for defaults:
109
+ query_root_type = types['Query']
110
+ mutation_root_type = types['Mutation']
111
+ subscription_root_type = types['Subscription']
112
+ end
102
113
  else
103
114
  query_root_type = types['Query']
104
115
  mutation_root_type = types['Mutation']
@@ -107,6 +118,8 @@ module GraphQL
107
118
 
108
119
  raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
109
120
 
121
+ builder = self
122
+
110
123
  schema_class = Class.new(schema_superclass) do
111
124
  begin
112
125
  # Add these first so that there's some chance of resolving late-bound types
@@ -134,6 +147,7 @@ module GraphQL
134
147
 
135
148
  if schema_definition
136
149
  ast_node(schema_definition)
150
+ builder.build_directives(self, schema_definition, type_resolver)
137
151
  end
138
152
 
139
153
  using.each do |plugin, options|
@@ -361,8 +375,6 @@ module GraphQL
361
375
  end
362
376
  end
363
377
 
364
- NO_DEFAULT_VALUE = {}.freeze
365
-
366
378
  def build_arguments(type_class, arguments, type_resolver)
367
379
  builder = self
368
380
 
@@ -370,7 +382,7 @@ module GraphQL
370
382
  default_value_kwargs = if !argument_defn.default_value.nil?
371
383
  { default_value: builder.build_default_value(argument_defn.default_value) }
372
384
  else
373
- NO_DEFAULT_VALUE
385
+ EMPTY_HASH
374
386
  end
375
387
 
376
388
  type_class.argument(
@@ -25,19 +25,16 @@ module GraphQL
25
25
  include GraphQL::Schema::Member::HasDirectives
26
26
  include GraphQL::Schema::Member::HasDeprecationReason
27
27
 
28
- UNDEFINED_VALUE = Object.new.freeze
29
- private_constant :UNDEFINED_VALUE
30
-
31
28
  attr_reader :graphql_name
32
29
 
33
30
  # @return [Class] The enum type that owns this value
34
31
  attr_reader :owner
35
32
 
36
- def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: UNDEFINED_VALUE, deprecation_reason: nil, &block)
33
+ def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: NOT_CONFIGURED, deprecation_reason: nil, &block)
37
34
  @graphql_name = graphql_name.to_s
38
35
  GraphQL::NameValidator.validate!(@graphql_name)
39
36
  @description = desc || description
40
- @value = value === UNDEFINED_VALUE ? @graphql_name : value
37
+ @value = value === NOT_CONFIGURED ? @graphql_name : value
41
38
  if deprecation_reason
42
39
  self.deprecation_reason = deprecation_reason
43
40
  end
@@ -11,7 +11,7 @@ module GraphQL
11
11
  include GraphQL::Schema::Member::HasPath
12
12
  include GraphQL::Schema::Member::HasValidators
13
13
  extend GraphQL::Schema::FindInheritedValue
14
- include GraphQL::Schema::FindInheritedValue::EmptyObjects
14
+ include GraphQL::EmptyObjects
15
15
  include GraphQL::Schema::Member::HasDirectives
16
16
  include GraphQL::Schema::Member::HasDeprecationReason
17
17
 
@@ -219,7 +219,7 @@ module GraphQL
219
219
  # @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
220
220
  # @param validates [Array<Hash>] Configurations for validating this field
221
221
  # @fallback_value [Object] A fallback value if the method is not defined
222
- def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: :not_given, &definition_block)
222
+ def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: NOT_CONFIGURED, &definition_block)
223
223
  if name.nil?
224
224
  raise ArgumentError, "missing first `name` argument or keyword `name:`"
225
225
  end
@@ -608,15 +608,16 @@ module GraphQL
608
608
  # The resolver _instance_ will check itself during `resolve()`
609
609
  @resolver_class.authorized?(object, context)
610
610
  else
611
- if (arg_values = context[:current_arguments])
612
- # ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
613
- using_arg_values = true
614
- arg_values = arg_values.argument_values
615
- else
616
- arg_values = args
617
- using_arg_values = false
618
- end
619
611
  if args.size > 0
612
+ if (arg_values = context[:current_arguments])
613
+ # ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
614
+ using_arg_values = true
615
+ arg_values = arg_values.argument_values
616
+ else
617
+ arg_values = args
618
+ using_arg_values = false
619
+ end
620
+
620
621
  args = context.warden.arguments(self)
621
622
  args.each do |arg|
622
623
  arg_key = arg.keyword
@@ -684,7 +685,7 @@ module GraphQL
684
685
  if hash_value == false
685
686
  hash_value
686
687
  else
687
- hash_value || (@fallback_value != :not_given ? @fallback_value : nil)
688
+ hash_value || (@fallback_value != NOT_CONFIGURED ? @fallback_value : nil)
688
689
  end
689
690
  elsif obj.respond_to?(resolver_method)
690
691
  method_to_call = resolver_method
@@ -702,7 +703,7 @@ module GraphQL
702
703
  inner_object[@method_sym]
703
704
  elsif inner_object.key?(@method_str)
704
705
  inner_object[@method_str]
705
- elsif @fallback_value != :not_given
706
+ elsif @fallback_value != NOT_CONFIGURED
706
707
  @fallback_value
707
708
  else
708
709
  nil
@@ -715,7 +716,7 @@ module GraphQL
715
716
  else
716
717
  inner_object.public_send(@method_sym)
717
718
  end
718
- elsif @fallback_value != :not_given
719
+ elsif @fallback_value != NOT_CONFIGURED
719
720
  @fallback_value
720
721
  else
721
722
  raise <<-ERR
@@ -752,6 +753,8 @@ module GraphQL
752
753
  end
753
754
  # if the line above doesn't raise, re-raise
754
755
  raise
756
+ rescue GraphQL::ExecutionError => err
757
+ err
755
758
  end
756
759
 
757
760
  # @param ctx [GraphQL::Query::Context]
@@ -71,14 +71,11 @@ module GraphQL
71
71
  elsif inherited_extras
72
72
  inherited_extras
73
73
  else
74
- NO_EXTRAS
74
+ GraphQL::EmptyObjects::EMPTY_ARRAY
75
75
  end
76
76
  end
77
77
  end
78
78
 
79
- NO_EXTRAS = [].freeze
80
- private_constant :NO_EXTRAS
81
-
82
79
  # Called when this extension is attached to a field.
83
80
  # The field definition may be extended during this method.
84
81
  # @return [void]
@@ -2,17 +2,12 @@
2
2
  module GraphQL
3
3
  class Schema
4
4
  module FindInheritedValue
5
- module EmptyObjects
6
- EMPTY_HASH = {}.freeze
7
- EMPTY_ARRAY = [].freeze
8
- end
9
-
10
5
  def self.extended(child_cls)
11
- child_cls.singleton_class.include(EmptyObjects)
6
+ child_cls.singleton_class.include(GraphQL::EmptyObjects)
12
7
  end
13
8
 
14
9
  def self.included(child_cls)
15
- child_cls.include(EmptyObjects)
10
+ child_cls.include(GraphQL::EmptyObjects)
16
11
  end
17
12
 
18
13
  private
@@ -46,7 +46,7 @@ module GraphQL
46
46
  elsif defined?(@description)
47
47
  @description
48
48
  else
49
- nil
49
+ @description = nil
50
50
  end
51
51
  end
52
52
 
@@ -56,8 +56,12 @@ module GraphQL
56
56
  def inherited(child_class)
57
57
  child_class.introspection(introspection)
58
58
  child_class.description(description)
59
- if defined?(@graphql_name) && (self.name.nil? || graphql_name != default_graphql_name)
59
+ child_class.default_graphql_name = nil
60
+
61
+ if defined?(@graphql_name) && @graphql_name && (self.name.nil? || graphql_name != default_graphql_name)
60
62
  child_class.graphql_name(graphql_name)
63
+ else
64
+ child_class.graphql_name = nil
61
65
  end
62
66
  super
63
67
  end
@@ -98,7 +102,8 @@ module GraphQL
98
102
  def default_graphql_name
99
103
  @default_graphql_name ||= begin
100
104
  raise GraphQL::RequiredImplementationMissingError, 'Anonymous class should declare a `graphql_name`' if name.nil?
101
- -name.split("::").last.sub(/Type\Z/, "") end
105
+ -name.split("::").last.sub(/Type\Z/, "")
106
+ end
102
107
  end
103
108
 
104
109
  def visible?(context)
@@ -109,16 +114,13 @@ module GraphQL
109
114
  true
110
115
  end
111
116
 
112
- protected
113
-
114
- attr_writer :default_graphql_name
117
+ def default_relay
118
+ false
119
+ end
115
120
 
116
- private
121
+ protected
117
122
 
118
- def inherited(subclass)
119
- super
120
- subclass.default_graphql_name = nil
121
- end
123
+ attr_writer :default_graphql_name, :graphql_name
122
124
  end
123
125
  end
124
126
  end
@@ -413,7 +413,7 @@ module GraphQL
413
413
  end
414
414
  end
415
415
 
416
- NO_ARGUMENTS = {}.freeze
416
+ NO_ARGUMENTS = GraphQL::EmptyObjects::EMPTY_HASH
417
417
  def own_arguments
418
418
  @own_arguments || NO_ARGUMENTS
419
419
  end
@@ -3,6 +3,16 @@ module GraphQL
3
3
  class Schema
4
4
  class Member
5
5
  module HasAstNode
6
+ def self.extended(child_cls)
7
+ super
8
+ child_cls.ast_node = nil
9
+ end
10
+
11
+ def inherited(child_cls)
12
+ super
13
+ child_cls.ast_node = nil
14
+ end
15
+
6
16
  # If this schema was parsed from a `.graphql` file (or other SDL),
7
17
  # this is the AST node that defined this part of the schema.
8
18
  def ast_node(new_ast_node = nil)
@@ -14,6 +24,8 @@ module GraphQL
14
24
  nil
15
25
  end
16
26
  end
27
+
28
+ attr_writer :ast_node
17
29
  end
18
30
  end
19
31
  end
@@ -4,6 +4,16 @@ module GraphQL
4
4
  class Schema
5
5
  class Member
6
6
  module HasDirectives
7
+ def self.extended(child_cls)
8
+ super
9
+ child_cls.module_eval { self.own_directives = nil }
10
+ end
11
+
12
+ def inherited(child_cls)
13
+ super
14
+ child_cls.own_directives = nil
15
+ end
16
+
7
17
  # Create an instance of `dir_class` for `self`, using `options`.
8
18
  #
9
19
  # It removes a previously-attached instance of `dir_class`, if there is one.
@@ -23,8 +33,6 @@ module GraphQL
23
33
  nil
24
34
  end
25
35
 
26
- NO_DIRECTIVES = [].freeze
27
-
28
36
  def directives
29
37
  HasDirectives.get_directives(self, @own_directives, :directives)
30
38
  end
@@ -45,7 +53,7 @@ module GraphQL
45
53
  inherited_directives = if schema_member.superclass.respond_to?(directives_method)
46
54
  get_directives(schema_member.superclass, schema_member.superclass.public_send(directives_method), directives_method)
47
55
  else
48
- NO_DIRECTIVES
56
+ GraphQL::EmptyObjects::EMPTY_ARRAY
49
57
  end
50
58
  if inherited_directives.any? && directives
51
59
  dirs = []
@@ -57,7 +65,7 @@ module GraphQL
57
65
  elsif inherited_directives.any?
58
66
  inherited_directives
59
67
  else
60
- NO_DIRECTIVES
68
+ GraphQL::EmptyObjects::EMPTY_ARRAY
61
69
  end
62
70
  when Module
63
71
  dirs = nil
@@ -72,9 +80,9 @@ module GraphQL
72
80
  dirs ||= []
73
81
  merge_directives(dirs, directives)
74
82
  end
75
- dirs || NO_DIRECTIVES
83
+ dirs || GraphQL::EmptyObjects::EMPTY_ARRAY
76
84
  when HasDirectives
77
- directives || NO_DIRECTIVES
85
+ directives || GraphQL::EmptyObjects::EMPTY_ARRAY
78
86
  else
79
87
  raise "Invariant: how could #{schema_member} not be a Class, Module, or instance of HasDirectives?"
80
88
  end
@@ -101,12 +109,9 @@ module GraphQL
101
109
  end
102
110
  end
103
111
 
104
-
105
112
  protected
106
113
 
107
- def own_directives
108
- @own_directives
109
- end
114
+ attr_accessor :own_directives
110
115
  end
111
116
  end
112
117
  end