-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathgen_ast.rb
executable file
·184 lines (148 loc) · 5.01 KB
/
gen_ast.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/usr/bin/ruby
VERSION_TAG = "v14.3.0"
url = "https://raw.githubusercontent.com/graphql/graphql-js/#{ VERSION_TAG }/src/language/ast.js"
# Local for development...
# url = "http://127.0.0.1/ast.js"
javascript = `curl --silent '#{ url }'`
haxe = javascript
File.open('/tmp/ast.js', 'w') { |f| f.puts javascript }
haxe.gsub!(/export type/, "typedef /* export type */")
haxe.gsub!(/(\w+)\?:(\s+\?)?/, "?\\1 /* opt */ :")
# Basic types
haxe.gsub!(/:\s*boolean\b/, ":Bool")
haxe.gsub!(/:\s*string\b/, ":String")
haxe.gsub!(/:\s*number\b/, ":Int /* number */")
# Remove lading + signs
haxe.gsub!(/^(\s+)\+/, "\\1")
# Remove pipes from {| |}
haxe.gsub!(/{\|/, "{").gsub!(/\|}/, "}")
# Replace node unions with BaseNode
haxe.gsub!(/Node =(\s*\n\s+\|.*?;)/m, "Node = BaseNode; /* \\1 */")
haxe.gsub!(/Node = (\w+\s+\|.*?;)/, "Node = BaseNode; /* \\1 */")
haxe.gsub!(/\bNamedTypeNode \| ListTypeNode\b/, "TypeNode /* NamedTypeNode | ListTypeNode */")
haxe.gsub!(/^(typedef .*? TypeNode .*)/, "// \\1")
haxe.gsub!(/^\s+(prev|next):\s*Token \| null/, " ?\\1: Null<Token>")
haxe.gsub!(/value:String \| void/, "?value:Null<String>")
# Comment out imports
haxe.gsub!(/^(import type .*)/, "// \\1")
haxe.gsub!(/^(import { type .*)/, "// \\1")
# Kind string consts
haxe.gsub!(/kind: ('\w+')/, "kind: String, // \\1")
haxe.gsub!(/\$ReadOnlyArray/, "/* $ReadOnlyArray */Array");
op_type = <<eof
@:enum abstract OperationTypeNode(String) to String from String {
var QUERY = 'query';
var MUTATION = 'mutation';
var SUBSCRIPTION = 'subscription'; // experimental non-spec
}
eof
haxe.gsub!(/(typedef .*? OperationTypeNode.*)/, "// \\1 \n#{ op_type }")
# - - - - write output
puts <<eof
package graphql;
/* GENERATED BY gen_ast.rb -- DO NOT EDIT!!! */
/* GENERATED BY gen_ast.rb -- DO NOT EDIT!!! */
/* GENERATED BY gen_ast.rb -- DO NOT EDIT!!! */
/* GENERATED BY gen_ast.rb -- DO NOT EDIT!!! */
/* */
/* based on: #{ url } */
/* */
typedef TokenKindEnum = TokenKind;
typedef Source = graphql.parser.StringSlice;
typedef BaseNode = {
kind:String,
?loc:Location
}
// Type nodes -- kind of a lie, but meh
typedef TypeNode = { > BaseNode,
// Calling these optionals makes us able to simply null-check them:
?name: NameNode, // Only for NamedTypeNode
?type: TypeNode, // Not for NamedTypeNode
?operationTypes: Array<OperationTypeDefinitionNode>,
?directives: Array<DirectiveNode>,
}
// typedef NamedOrListTypeNode = BaseNode; // NamedTypeNode | ListTypeNode
// TokenKind
@:enum abstract TokenKind(String) to String from String {
var SOF = '<SOF>';
var EOF = '<EOF>';
var BANG = '!';
var DOLLAR = '$';
var AMP = '&';
var PAREN_L = '(';
var PAREN_R = ')';
var SPREAD = '...';
var COLON = ':';
var EQUALS = '=';
var AT = '@';
var BRACKET_L = '[';
var BRACKET_R = ']';
var BRACE_L = '{';
var PIPE = '|';
var BRACE_R = '}';
var NAME = 'Name';
var INT = 'Int';
var FLOAT = 'Float';
var STRING = 'String';
var BLOCK_STRING = 'BlockString';
var COMMENT = 'Comment';
}
// Kind
@:enum abstract Kind(String) to String from String {
// Name
var NAME = 'Name';
// Document
var DOCUMENT = 'Document';
var OPERATION_DEFINITION = 'OperationDefinition';
var VARIABLE_DEFINITION = 'VariableDefinition';
var VARIABLE = 'Variable';
var SELECTION_SET = 'SelectionSet';
var FIELD = 'Field';
var ARGUMENT = 'Argument';
// Fragments
var FRAGMENT_SPREAD = 'FragmentSpread';
var INLINE_FRAGMENT = 'InlineFragment';
var FRAGMENT_DEFINITION = 'FragmentDefinition';
// Values
var INT = 'IntValue';
var FLOAT = 'FloatValue';
var STRING = 'StringValue';
var BOOLEAN = 'BooleanValue';
var NULL = 'NullValue';
var ENUM = 'EnumValue';
var LIST = 'ListValue';
var OBJECT = 'ObjectValue';
var OBJECT_FIELD = 'ObjectField';
// Directives
var DIRECTIVE = 'Directive';
// Types
var NAMED_TYPE = 'NamedType';
var LIST_TYPE = 'ListType';
var NON_NULL_TYPE = 'NonNullType';
// Type System Definitions
var SCHEMA_DEFINITION = 'SchemaDefinition';
var SCHEMA_EXTENSION = 'SchemaExtension';
var OPERATION_TYPE_DEFINITION = 'OperationTypeDefinition';
// Type Definitions
var SCALAR_TYPE_DEFINITION = 'ScalarTypeDefinition';
var OBJECT_TYPE_DEFINITION = 'ObjectTypeDefinition';
var FIELD_DEFINITION = 'FieldDefinition';
var INPUT_VALUE_DEFINITION = 'InputValueDefinition';
var INTERFACE_TYPE_DEFINITION = 'InterfaceTypeDefinition';
var UNION_TYPE_DEFINITION = 'UnionTypeDefinition';
var ENUM_TYPE_DEFINITION = 'EnumTypeDefinition';
var ENUM_VALUE_DEFINITION = 'EnumValueDefinition';
var INPUT_OBJECT_TYPE_DEFINITION = 'InputObjectTypeDefinition';
// Type Extensions
var SCALAR_TYPE_EXTENSION = 'ScalarTypeExtension';
var OBJECT_TYPE_EXTENSION = 'ObjectTypeExtension';
var INTERFACE_TYPE_EXTENSION = 'InterfaceTypeExtension';
var UNION_TYPE_EXTENSION = 'UnionTypeExtension';
var ENUM_TYPE_EXTENSION = 'EnumTypeExtension';
var INPUT_OBJECT_TYPE_EXTENSION = 'InputObjectTypeExtension';
// Directive Definitions
var DIRECTIVE_DEFINITION = 'DirectiveDefinition';
}
class ASTDefs { }
#{ haxe }
eof