-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathgen_parser.rb
executable file
·189 lines (139 loc) · 6.47 KB
/
gen_parser.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
185
186
187
188
189
#!/usr/bin/ruby
require_relative './gen_shared'
VERSION_TAG = "v14.3.0"
url = "https://raw.githubusercontent.com/graphql/graphql-js/#{ VERSION_TAG }/src/language/parser.js"
javascript = `curl --silent '#{ url }'`
haxe = javascript
haxe.sub!(/(import {.*?directiveLocation';)/m) { |imports| "/* #{ imports.gsub(/{/, "BR_L") } */" }
# Comment out imports
haxe.gsub!(/^(import .*?from)/, "// \\1")
GenShared::export_type_to_typedef!(haxe)
#haxe.gsub!(/export type/, "typedef /* export type */")
#haxe.gsub!(/(\w+)\?:(\s+\?)?/, "?\\1 /* opt */ :")
GenShared::export_to_function!(haxe)
haxe.gsub!(/string\s*\|\s*Source/, "JustSource")
GenShared::backticks!(haxe)
GenShared::basic_types_and_junk!(haxe)
GenShared::func_args_trailing_comma!(haxe)
GenShared::func_calls_trailing_comma!(haxe)
# ESIOK... ES implied object key name... GRR!
haxe = GenShared::ES_implied_object_keys(haxe)
# Should be working for nested now...
### #haxe.gsub!(/(kind:\s*Kind\.\w+,\s*\n\s*)(type|directives|operation),/, "\\1\\2:\\2, /* ESIOK2 */")
### #haxe.gsub!(/^(\s+)(operationTypes|type|description|name|directives|interfaces|fields|types|values|locations),\s*$/, "\\1\\2:\\2, /* ESIOK3 */")
# Inject GeneratedParser class definition
haxe.sub!(/^(public function parse\()/m, "\n\n/**/\n/**/\n/**/\nclass GeneratedParser {\n\n\n\\1")
haxe.sub!(/^public function parse\(.*?return parseDocu.*?}/m, "/* Removed top-level parse() function */\n public function new() { }")
haxe.sub!(/private function parseDocument/, "public function parseDocument")
# Lexer<*> to just Lexer
haxe.gsub!(/Lexer<.>/, "Lexer")
haxe.gsub!("if (!lexer.options.noLocation)", "/* noLocation disabled */")
# Remove Loc "class"
haxe.sub!(/^private function loc\(.*?defineToJSON.*?}\);/m, "/* class / function Loc() removed */")
haxe.sub!(/new Loc\(startToken, lexer.lastToken, lexer.source\)/, "({ start:startToken.start, end:lexer.lastToken.end, source:lexer.source, startToken:startToken, endToken:lexer.lastToken }:Location)")
# Some unions
haxe.gsub!(/Location \| void/, "Location /* | void */")
haxe.gsub!(/FragmentSpreadNode \| InlineFragmentNode/, "SomeFragmentNode")
haxe.gsub!(/void \| StringValueNode/, "Null<StringValueNode>")
# Comment out function parseType / parseValue
haxe.gsub!(/public function parseValue\(.*?function parseType\(.*?return type.*?}/m, "/* Removed parseValue() and parseType() */")
# Comment out function any<T>( )
# haxe.gsub!(/(private function (m)?any<.*?return nodes.*?})/m, "/*\n \\1 \n*/")
haxe.gsub!(/\(lexer: Lexer\) => T/, "Lexer->T")
# () block, currently only used with expect function
haxe.gsub!(/\((expect.*?\)),(.*?\))\)/, "{ \\1 ; \\2 ; } /* WTH (,) block */")
haxe.gsub!(/atToken \|\| lexer.token/, "atToken!=null ? atToken : lexer.token")
haxe.gsub!(/\bundefined\b/, "null/* undefined */")
# But there's one inside a comment :(
haxe.gsub!(/undefined \*\/\.\s+\*\//, "undefined\n */")
haxe.gsub!(/var (\w+);/, "var \\1=null /* INIT */;")
# syntax error now takes line and lineStart (for reporting pos)
haxe.gsub!(/syntaxError\(\s*lexer.source/m, "syntaxError(lexer.source, lexer.line, lexer.lineStart")
# Missing cases / break to throw
haxe.gsub!(/ break;(\s+}\s+throw)/m, "default: /* was break, fall through to throw */\n\\1")
GenShared::case_fall_throughs!(haxe)
# Need to cast some node types...
[ ["parseFragment", "typeCondition"],
["parseValueLiteral", "break"] ].each { |function_details|
function_name = function_details[0]
before_last_return = function_details[1]
haxe.gsub!(/function #{ function_name }\(.*?#{ before_last_return }.*?(return|throw).*?}/m) { |block|
block = "#{ block.gsub!(/return {/, "return /* CSMT */ cast {") }"
block
}
}
# Need to cast some node types...
[ ["parseTypeReference", "NonNullTypeNode"] ].each { |function_details|
function_name = function_details[0]
before_last_return = function_details[1]
haxe.gsub!(/function #{ function_name }\(.*?#{ before_last_return }.*?(return).*?}/m) { |block|
block = "#{ block.gsub!(/ \({/, " /* CSMT2 */ ( cast {") }"
block.gsub!(/(: \w+TypeNode)/, "/* \\1 */")
block.sub!(/type = parseNamed/, "type = /* */ cast parseNamed")
block
}
}
# Irritating null return syntax
haxe.gsub!(/(parseDescription.*?)if (\(peekDescription.*?\)) {/m, "\\1if (!\\2) return null; {")
haxe.gsub!(/DirectiveLocation.hasOwnProperty/, "ValidDirectiveLocations.get")
# arrow function
haxe.sub!(/item = \(\) => parseObjectField\(/, "item = function(?lxr) return parseObjectField(")
# comment out Loc defineToJSON
haxe.sub!(/(defineToJSON\(Loc.*?}\);)/m, "/* \\1 */")
# expectOptionalKeyword and expectOptionalToken should return Bool
haxe.gsub!(/(tion expectOptional.*?return null)/m) { |blk|
blk.sub!(/(tion expectOptional.*?\)\s*:)\s*\?\s*(\w+)\s*/, "\\1Bool");
blk.sub!(/return token/, "return token!=null");
blk.sub!(/return null/, "return false");
blk
}
# - - - - write output
puts <<eof
package graphql.parser;
/* GENERATED BY gen_parser.rb -- DO NOT EDIT!!! */
/* GENERATED BY gen_parser.rb -- DO NOT EDIT!!! */
/* GENERATED BY gen_parser.rb -- DO NOT EDIT!!! */
/* GENERATED BY gen_parser.rb -- DO NOT EDIT!!! */
/* */
/* based on: #{ url } */
/* */
import graphql.ASTDefs;
import graphql.parser.GeneratedLexer;
// Move this to ASTDefs?
typedef SomeFragmentNode = BaseNode; // FragmentSpreadNode | InlineFragmentNode
typedef TODO = { };
typedef GraphQLError = { };
typedef Lexer = GeneratedLexer<ParseOptions>;
#{ haxe }
private function loc(lexer: Lexer, startToken: Token): Location /* | void */ {
if (lexer.options!=null && lexer.options.noLocation) return null;
return { start:startToken.start, end:lexer.lastToken.end, startToken:startToken, endToken:lexer.lastToken, source:lexer.source };
}
private function syntaxError(source:Source, line:Int, lineStart:Int, start:Int, msg:String): GraphQLError {
return graphql.parser.Parser.syntaxError(source, line, lineStart, start, msg);
}
private function getTokenDesc(t:Token) return t.kind;
static var ValidDirectiveLocations:haxe.ds.StringMap<Bool> = [
// Request Definitions
'QUERY' => true,
'MUTATION' => true,
'SUBSCRIPTION' => true,
'FIELD' => true,
'FRAGMENT_DEFINITION' => true,
'FRAGMENT_SPREAD' => true,
'INLINE_FRAGMENT' => true,
// Type System Definitions
'SCHEMA' => true,
'SCALAR' => true,
'OBJECT' => true,
'FIELD_DEFINITION' => true,
'ARGUMENT_DEFINITION' => true,
'INTERFACE' => true,
'UNION' => true,
'ENUM' => true,
'ENUM_VALUE' => true,
'INPUT_OBJECT' => true,
'INPUT_FIELD_DEFINITION' => true
];
} // end of class GeneratedParser
eof