Skip to content

Commit 3a0a17b

Browse files
committed
Avoid needless type checks at runtime
1 parent cb8a6f9 commit 3a0a17b

File tree

1 file changed

+81
-36
lines changed

1 file changed

+81
-36
lines changed

lib/graphql/schema/member/has_fields.rb

Lines changed: 81 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,6 @@ def field(*args, **kwargs, &block)
1414
field_defn
1515
end
1616

17-
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
18-
def fields(context = GraphQL::Query::NullContext)
19-
warden = Warden.from_context(context)
20-
is_object = self.respond_to?(:kind) && self.kind.object?
21-
# Local overrides take precedence over inherited fields
22-
visible_fields = {}
23-
for ancestor in ancestors
24-
if ancestor.respond_to?(:own_fields) &&
25-
(is_object ? visible_interface_implementation?(ancestor, context, warden) : true)
26-
27-
ancestor.own_fields.each do |field_name, fields_entry|
28-
# Choose the most local definition that passes `.visible?` --
29-
# stop checking for fields by name once one has been found.
30-
if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
31-
visible_fields[field_name] = f
32-
end
33-
end
34-
end
35-
end
36-
visible_fields
37-
end
38-
39-
def get_field(field_name, context = GraphQL::Query::NullContext)
40-
warden = Warden.from_context(context)
41-
is_object = self.respond_to?(:kind) && self.kind.object?
42-
for ancestor in ancestors
43-
if ancestor.respond_to?(:own_fields) &&
44-
(is_object ? visible_interface_implementation?(ancestor, context, warden) : true) &&
45-
(f_entry = ancestor.own_fields[field_name]) &&
46-
(f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
47-
return f
48-
end
49-
end
50-
nil
51-
end
52-
5317
# A list of Ruby keywords.
5418
#
5519
# @api private
@@ -132,6 +96,87 @@ def all_field_definitions
13296
all_fields
13397
end
13498

99+
module InterfaceMethods
100+
def get_field(field_name, context = GraphQL::Query::NullContext)
101+
warden = Warden.from_context(context)
102+
for ancestor in ancestors
103+
if ancestor.respond_to?(:own_fields) &&
104+
(f_entry = ancestor.own_fields[field_name]) &&
105+
(f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
106+
return f
107+
end
108+
end
109+
nil
110+
end
111+
112+
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
113+
def fields(context = GraphQL::Query::NullContext)
114+
warden = Warden.from_context(context)
115+
# Local overrides take precedence over inherited fields
116+
visible_fields = {}
117+
for ancestor in ancestors
118+
if ancestor.respond_to?(:own_fields)
119+
ancestor.own_fields.each do |field_name, fields_entry|
120+
# Choose the most local definition that passes `.visible?` --
121+
# stop checking for fields by name once one has been found.
122+
if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
123+
visible_fields[field_name] = f
124+
end
125+
end
126+
end
127+
end
128+
visible_fields
129+
end
130+
end
131+
132+
module ObjectMethods
133+
def get_field(field_name, context = GraphQL::Query::NullContext)
134+
# Objects need to check that the interface implementation is visible, too
135+
warden = Warden.from_context(context)
136+
for ancestor in ancestors
137+
if ancestor.respond_to?(:own_fields) &&
138+
visible_interface_implementation?(ancestor, context, warden) &&
139+
(f_entry = ancestor.own_fields[field_name]) &&
140+
(f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
141+
return f
142+
end
143+
end
144+
nil
145+
end
146+
147+
148+
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
149+
def fields(context = GraphQL::Query::NullContext)
150+
# Objects need to check that the interface implementation is visible, too
151+
warden = Warden.from_context(context)
152+
# Local overrides take precedence over inherited fields
153+
visible_fields = {}
154+
for ancestor in ancestors
155+
if ancestor.respond_to?(:own_fields) && visible_interface_implementation?(ancestor, context, warden)
156+
ancestor.own_fields.each do |field_name, fields_entry|
157+
# Choose the most local definition that passes `.visible?` --
158+
# stop checking for fields by name once one has been found.
159+
if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
160+
visible_fields[field_name] = f
161+
end
162+
end
163+
end
164+
end
165+
visible_fields
166+
end
167+
end
168+
169+
def self.included(child_class)
170+
# Included in an interface definition methods module
171+
child_class.include(InterfaceMethods)
172+
super
173+
end
174+
175+
def self.extended(child_class)
176+
child_class.extend(ObjectMethods)
177+
super
178+
end
179+
135180
private
136181

137182
def inherited(subclass)

0 commit comments

Comments
 (0)