Skip to content

Commit 01c1637

Browse files
committed
refactor(Execution) isolate some execution helpers
1 parent e5bee84 commit 01c1637

File tree

11 files changed

+75
-62
lines changed

11 files changed

+75
-62
lines changed

lib/graphql.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ def self.parse_with_racc(string)
7070
require "graphql/static_validation"
7171
require "graphql/version"
7272
require "graphql/relay"
73+
require "graphql/execution"

lib/graphql/analysis/query_complexity.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ def call(memo, visit_type, irep_node)
3232
memo[:complexities_on_type].push(TypeComplexity.new)
3333
else
3434
type_complexities = memo[:complexities_on_type].pop
35-
own_complexity = if GraphQL::Query::DirectiveResolution.include_node?(irep_node, memo[:query])
35+
own_complexity = if GraphQL::Execution::DirectiveChecks.skip?(irep_node, memo[:query])
36+
0
37+
else
3638
child_complexity = type_complexities.max_possible_complexity
3739
get_complexity(irep_node, memo[:query], child_complexity)
38-
else
39-
0
4040
end
4141
memo[:complexities_on_type].last.merge(irep_node.definitions, own_complexity)
4242
end

lib/graphql/analysis/query_depth.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ def call(memo, visit_type, irep_node)
2929
memo[:skip_current_scope] = true
3030
elsif memo[:skip_current_scope]
3131
# we're inside an introspection query
32-
elsif GraphQL::Query::DirectiveResolution.include_node?(irep_node, memo[:query])
32+
elsif GraphQL::Execution::DirectiveChecks.include?(irep_node, memo[:query])
3333
memo[:current_depth] += 1
3434
end
3535
else
3636
if GraphQL::Schema::DYNAMIC_FIELDS.include?(irep_node.definition_name)
3737
memo[:skip_current_scope] = false
38-
elsif GraphQL::Query::DirectiveResolution.include_node?(irep_node, memo[:query])
38+
elsif GraphQL::Execution::DirectiveChecks.include?(irep_node, memo[:query])
3939
if memo[:max_depth] < memo[:current_depth]
4040
memo[:max_depth] = memo[:current_depth]
4141
end

lib/graphql/execution.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require "graphql/execution/directive_checks"
2+
require "graphql/execution/typecast"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module GraphQL
2+
module Execution
3+
# Boolean checks for how an AST node's directives should
4+
# influence its execution
5+
module DirectiveChecks
6+
SKIP = "skip"
7+
INCLUDE = "include"
8+
9+
module_function
10+
11+
# This covers `@include(if:)` & `@skip(if:)`
12+
# @return [Boolean] Should this node be skipped altogether?
13+
def skip?(irep_node, query)
14+
irep_node.directives.each do |directive_node|
15+
if directive_node.name == SKIP || directive_node.name == INCLUDE
16+
directive_defn = directive_node.definitions.first
17+
args = query.arguments_for(directive_node, directive_defn)
18+
if !directive_defn.include?(args)
19+
return true
20+
end
21+
end
22+
end
23+
false
24+
end
25+
26+
# @return [Boolean] Should this node be included in the query?
27+
def include?(irep_node, query)
28+
!skip?(irep_node, query)
29+
end
30+
end
31+
end
32+
end

lib/graphql/execution/typecast.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module GraphQL
2+
module Execution
3+
# GraphQL object `{value, type}` can be cast to `other_type` when:
4+
# - `type == other_type`
5+
# - `type` is a union and it resolves `value` to `other_type`
6+
# - `other_type` is a union and `type` is a member
7+
# - `type` is an interface and it resolves `value` to `other_type`
8+
# - `other_type` is an interface and `type` implements that interface
9+
module Typecast
10+
# While `value` is exposed by GraphQL as an instance of `current_type`,
11+
# should it _also_ be treated as an instance of `potential_type`?
12+
#
13+
# This is used for checking whether fragments apply to an object.
14+
#
15+
# @return [Boolean] Can `value` be evaluated as a `potential_type`?
16+
def self.compatible?(value, current_type, potential_type, query_ctx)
17+
if potential_type == current_type
18+
true
19+
elsif current_type.kind.union?
20+
current_type.resolve_type(value, query_ctx) == potential_type
21+
elsif potential_type.kind.union?
22+
potential_type.include?(current_type)
23+
elsif current_type.kind.interface?
24+
current_type.resolve_type(value, query_ctx) == potential_type
25+
elsif potential_type.kind.interface?
26+
current_type.interfaces.include?(potential_type)
27+
else
28+
false
29+
end
30+
end
31+
end
32+
end
33+
end

lib/graphql/query.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
require "graphql/query/arguments"
22
require "graphql/query/context"
3-
require "graphql/query/directive_resolution"
43
require "graphql/query/executor"
54
require "graphql/query/literal_input"
65
require "graphql/query/serial_execution"
7-
require "graphql/query/type_resolver"
86
require "graphql/query/variables"
97
require "graphql/query/input_validation_result"
108
require "graphql/query/variable_validation_error"

lib/graphql/query/directive_resolution.rb

Lines changed: 0 additions & 16 deletions
This file was deleted.

lib/graphql/query/serial_execution/selection_resolution.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def initialize(target, type, irep_node, execution_context)
1313

1414
def result
1515
irep_node.children.each_with_object({}) do |(name, irep_node), memo|
16-
if included_by_directives?(irep_node, execution_context.query) && applies_to_type?(irep_node, type, target)
16+
if GraphQL::Execution::DirectiveChecks.include?(irep_node, execution_context.query) && applies_to_type?(irep_node, type, target)
1717
field_result = execution_context.strategy.field_resolution.new(
1818
irep_node,
1919
type,
@@ -27,13 +27,9 @@ def result
2727

2828
private
2929

30-
def included_by_directives?(irep_node, query)
31-
GraphQL::Query::DirectiveResolution.include_node?(irep_node, query)
32-
end
33-
3430
def applies_to_type?(irep_node, type, target)
3531
irep_node.definitions.any? { |child_type, field_defn|
36-
GraphQL::Query::TypeResolver.new(target, child_type, type, execution_context.query.context).type
32+
GraphQL::Execution::Typecast.compatible?(target, child_type, type, execution_context.query.context)
3733
}
3834
end
3935
end

lib/graphql/query/type_resolver.rb

Lines changed: 0 additions & 25 deletions
This file was deleted.

spec/graphql/query/type_resolver_spec.rb

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)