Skip to content

Commit 87bb0c8

Browse files
committed
Describe query AST format in validate.lua
1 parent 2394ca1 commit 87bb0c8

File tree

2 files changed

+183
-0
lines changed

2 files changed

+183
-0
lines changed

graphql/core/parse.lua

+9
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ local function cField(...)
100100
local field = { kind = 'field' }
101101

102102
for i = 1, #tokens do
103+
-- key ~= nil => result['selectionSet'] = <...>
104+
-- or result['alias'] = <...>
105+
-- key == nil => result['arguments'] = <...>
106+
-- or result['directives'] = <...>
103107
local key = tokens[i].kind
104108
if not key then
105109
if tokens[i][1].kind == 'argument' then
@@ -145,6 +149,9 @@ local function cOperation(...)
145149
}
146150

147151
for i = 2, #args do
152+
-- key ~= nil => result['selectionSet'] = <...>
153+
-- key == nil => result['variableDefinitions'] = <...>
154+
-- or result['directives'] = <...>
148155
local key = args[i].kind
149156
if not key then
150157
if args[i][1].kind == 'variableDefinition' then
@@ -316,3 +323,5 @@ return function(str)
316323
line, lastLinePos = 1, 1
317324
return graphQL:match(str) or error('Syntax error near line ' .. line, 2)
318325
end
326+
327+
-- vim: set ts=2 sw=2 et:

graphql/core/validate.lua

+174
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ local function getParentField(context, name, count)
1919
end
2020

2121
local visitors = {
22+
-- <document>
23+
--
24+
-- {
25+
-- kind = 'document',
26+
-- definitions = list of <definition>,
27+
-- }
28+
--
29+
-- <definition> is one of the following:
30+
--
31+
-- * <operation>
32+
-- * <fragmentDefinition>
2233
document = {
2334
enter = function(node, context)
2435
for _, definition in ipairs(node.definitions) do
@@ -35,6 +46,47 @@ local visitors = {
3546
rules = { rules.uniqueFragmentNames, exit = { rules.noUnusedFragments } }
3647
},
3748

49+
-- <operation>
50+
--
51+
-- {
52+
-- kind = 'operation',
53+
-- operation = 'query' or 'mutation',
54+
-- selectionSet = <selectionSet>,
55+
-- variableDefinitions = list of <variableDefinition> (optional),
56+
-- directives = list of <directive> (optional),
57+
-- }
58+
--
59+
-- <variableDefinition>
60+
--
61+
-- {
62+
-- kind = 'variableDefinition',
63+
-- variable = <variable>,
64+
-- type = <type>,
65+
-- defaultValue = <value> (optional)
66+
-- }
67+
--
68+
-- <type> is one of the following:
69+
--
70+
-- * <namedType>
71+
-- * <listType>
72+
-- * <nonNullType>
73+
--
74+
-- <namedType>
75+
--
76+
-- {
77+
-- kind = 'namedType',
78+
-- name = {
79+
-- kind = 'name',
80+
-- value = <string>,
81+
-- },
82+
-- }
83+
--
84+
-- <listType>, <nonNullType>
85+
--
86+
-- {
87+
-- kind = one of ('listType', 'nonNullType'),
88+
-- type = <type>,
89+
-- }
3890
operation = {
3991
enter = function(node, context)
4092
table.insert(context.objects, context.schema[node.operation])
@@ -65,6 +117,18 @@ local visitors = {
65117
}
66118
},
67119

120+
-- <selectionSet>
121+
--
122+
-- {
123+
-- kind = 'selectionSet',
124+
-- selections = list of <selection>,
125+
-- }
126+
--
127+
-- <selection> is one of the following:
128+
--
129+
-- * <field>
130+
-- * <fragmentSpread>
131+
-- * <inlineFragment>
68132
selectionSet = {
69133
children = function(node)
70134
return node.selections
@@ -73,6 +137,22 @@ local visitors = {
73137
rules = { rules.unambiguousSelections }
74138
},
75139

140+
-- <field>
141+
--
142+
-- {
143+
-- kind = 'field',
144+
-- selectionSet = <selectionSet> (optional),
145+
-- alias = <alias> (optional),
146+
-- arguments = list of <argument> (optional),
147+
-- directives = list of <directive> (optional),
148+
-- }
149+
--
150+
-- <alias>
151+
--
152+
-- {
153+
-- kind = 'alias',
154+
-- name = <string>,
155+
-- }
76156
field = {
77157
enter = function(node, context)
78158
local name = node.name.value
@@ -125,6 +205,14 @@ local visitors = {
125205
}
126206
},
127207

208+
-- <inlineFragment>
209+
--
210+
-- {
211+
-- kind = 'inlineFragment',
212+
-- selectionSet = <selectionSet>,
213+
-- typeCondition = <namedType> (optional),
214+
-- directives = list of <directive> (optional),
215+
-- }
128216
inlineFragment = {
129217
enter = function(node, context)
130218
local kind = false
@@ -153,6 +241,16 @@ local visitors = {
153241
}
154242
},
155243

244+
-- <fragmentSpread>
245+
--
246+
-- {
247+
-- kind = 'fragmentSpread',
248+
-- name = {
249+
-- kind = 'name',
250+
-- value = <string>,
251+
-- },
252+
-- directives = list of <directive> (optional),
253+
-- }
156254
fragmentSpread = {
157255
enter = function(node, context)
158256
context.usedFragments[node.name.value] = true
@@ -218,6 +316,17 @@ local visitors = {
218316
}
219317
},
220318

319+
-- <fragmentDefinition>
320+
--
321+
-- {
322+
-- kind = 'fragmentDefinition',
323+
-- name = {
324+
-- kind = 'name',
325+
-- value = <string>,
326+
-- },
327+
-- typeCondition = <namedType>,
328+
-- selectionSet = <selectionSet>,
329+
-- }
221330
fragmentDefinition = {
222331
enter = function(node, context)
223332
local kind = context.schema:getType(node.typeCondition.name.value) or false
@@ -245,6 +354,41 @@ local visitors = {
245354
}
246355
},
247356

357+
-- <argument>
358+
--
359+
-- {
360+
-- kind = 'argument',
361+
-- name = {
362+
-- kind = 'name',
363+
-- value = <string>,
364+
-- },
365+
-- value = <value>,
366+
-- }
367+
--
368+
-- <value> is one of the following:
369+
--
370+
-- * <variable>
371+
-- * <inputObject>
372+
-- * <list>
373+
-- * <enum>
374+
-- * <string>
375+
-- * <boolean>
376+
-- * <float>
377+
-- * <int>
378+
--
379+
-- <list>
380+
--
381+
-- {
382+
-- kind = 'list',
383+
-- values = list of <value>,
384+
-- }
385+
--
386+
-- <enum>, <string>, <boolean>, <float>, <int>
387+
--
388+
-- {
389+
-- kind = one of ('enum', 'string', 'boolean', 'float', 'int'),
390+
-- value = <string>,
391+
-- }
248392
argument = {
249393
enter = function(node, context)
250394
if context.currentOperation then
@@ -268,6 +412,15 @@ local visitors = {
268412
rules = { rules.uniqueInputObjectFields }
269413
},
270414

415+
-- <inputObject>
416+
--
417+
-- {
418+
-- kind = 'inputObject',
419+
-- values = list of {
420+
-- name = <string>,
421+
-- value = <value>,
422+
-- }
423+
-- }
271424
inputObject = {
272425
children = function(node)
273426
return util.map(node.values or {}, function(value)
@@ -278,12 +431,31 @@ local visitors = {
278431
rules = { rules.uniqueInputObjectFields }
279432
},
280433

434+
-- <variable>
435+
--
436+
-- {
437+
-- kind = 'variable',
438+
-- name = {
439+
-- kind = 'name',
440+
-- value = <string>,
441+
-- }
442+
-- }
281443
variable = {
282444
enter = function(node, context)
283445
context.variableReferences[node.name.value] = true
284446
end
285447
},
286448

449+
-- <directive>
450+
--
451+
-- {
452+
-- kind = 'directive',
453+
-- name = {
454+
-- kind = 'name',
455+
-- value = <string>,
456+
-- },
457+
-- arguments = list of <argument> (optional),
458+
-- }
287459
directive = {
288460
children = function(node, context)
289461
return node.arguments
@@ -340,3 +512,5 @@ return function(schema, tree)
340512

341513
return visit(tree)
342514
end
515+
516+
-- vim: set ts=2 sw=2 et:

0 commit comments

Comments
 (0)