rapydscript-ng 0.7.23 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +72 -26
- package/bin/package.json +1 -0
- package/bin/rapydscript +65 -62
- package/editor-plugins/nvim/rapydscript/README.md +184 -0
- package/editor-plugins/nvim/rapydscript/bin/rapydscript.so +0 -0
- package/editor-plugins/nvim/rapydscript/ftdetect/rapydscript.lua +10 -0
- package/editor-plugins/nvim/rapydscript/lua/rapydscript/health.lua +88 -0
- package/editor-plugins/nvim/rapydscript/lua/rapydscript/init.lua +279 -0
- package/local-agent.md +28 -0
- package/package.json +4 -5
- package/release/baselib-plain-pretty.js +448 -326
- package/release/baselib-plain-ugly.js +3 -3
- package/release/compiler.js +2528 -1672
- package/release/signatures.json +17 -17
- package/src/ast.pyj +73 -25
- package/src/baselib-builtins.pyj +2 -2
- package/src/baselib-containers.pyj +153 -151
- package/src/baselib-internal.pyj +3 -3
- package/src/baselib-str.pyj +5 -5
- package/src/lib/aes.pyj +1 -1
- package/src/lib/encodings.pyj +1 -1
- package/src/lib/pythonize.pyj +1 -1
- package/src/lib/re.pyj +2 -2
- package/src/lib/traceback.pyj +165 -28
- package/src/lib/uuid.pyj +1 -1
- package/src/output/codegen.pyj +10 -3
- package/src/output/functions.pyj +31 -40
- package/src/output/literals.pyj +11 -14
- package/src/output/loops.pyj +25 -87
- package/src/output/modules.pyj +5 -47
- package/src/output/statements.pyj +1 -1
- package/src/output/stream.pyj +58 -31
- package/src/parse.pyj +777 -427
- package/src/tokenizer.pyj +16 -4
- package/src/utils.pyj +1 -1
- package/test/_treeshake_mod.pyj +30 -0
- package/test/_treeshake_side_effect.pyj +9 -0
- package/test/ast_serialization.pyj +392 -0
- package/test/async.pyj +95 -0
- package/test/baselib.pyj +1 -2
- package/test/embedded_compiler.pyj +57 -0
- package/test/fmt.pyj +201 -0
- package/test/generic.pyj +7 -3
- package/test/imports.pyj +8 -6
- package/test/internationalization.pyj +38 -37
- package/test/lint.pyj +120 -115
- package/test/lsp.pyj +222 -0
- package/test/repl.pyj +70 -65
- package/test/sourcemaps.pyj +315 -0
- package/test/starargs.pyj +46 -39
- package/test/traceback.pyj +263 -0
- package/test/treeshaking.pyj +181 -0
- package/test/web_repl_export.pyj +88 -0
- package/tools/ast_serialize.mjs +557 -0
- package/tools/cli.mjs +510 -0
- package/tools/compile.mjs +201 -0
- package/tools/compiler.mjs +127 -0
- package/tools/{completer.js → completer.mjs} +6 -6
- package/tools/{embedded_compiler.js → embedded_compiler.mjs} +17 -13
- package/tools/export.js +109 -56
- package/tools/fmt.mjs +735 -0
- package/tools/{gettext.js → gettext.mjs} +46 -53
- package/tools/{ini.js → ini.mjs} +9 -10
- package/tools/{lint.js → lint.mjs} +107 -56
- package/tools/lsp.mjs +914 -0
- package/tools/lsp_protocol.mjs +259 -0
- package/tools/lsp_symbols.mjs +418 -0
- package/tools/{msgfmt.js → msgfmt.mjs} +18 -18
- package/tools/{repl.js → repl.mjs} +52 -41
- package/tools/{self.js → self.mjs} +56 -46
- package/tools/sourcemap.mjs +123 -0
- package/tools/test.mjs +152 -0
- package/tools/treeshake.mjs +400 -0
- package/tools/{utils.js → utils.mjs} +26 -23
- package/tools/{web_repl.js → web_repl.mjs} +15 -13
- package/tools/web_repl_export.mjs +93 -0
- package/tree-sitter/README.md +101 -0
- package/tree-sitter/grammar.js +992 -0
- package/tree-sitter/package.json +43 -0
- package/tree-sitter/queries/rapydscript/highlights.scm +232 -0
- package/tree-sitter/queries/rapydscript/indents.scm +64 -0
- package/tree-sitter/queries/rapydscript/injections.scm +14 -0
- package/tree-sitter/queries/rapydscript/locals.scm +108 -0
- package/tree-sitter/src/grammar.json +4976 -0
- package/tree-sitter/src/node-types.json +2901 -0
- package/tree-sitter/src/parser.c +196465 -0
- package/tree-sitter/src/scanner.c +294 -0
- package/tree-sitter/src/tree_sitter/alloc.h +54 -0
- package/tree-sitter/src/tree_sitter/array.h +330 -0
- package/tree-sitter/src/tree_sitter/parser.h +286 -0
- package/tree-sitter/test/corpus/chaining.txt +99 -0
- package/tree-sitter/test/corpus/classes.txt +147 -0
- package/tree-sitter/test/corpus/comprehensions.txt +155 -0
- package/tree-sitter/test/corpus/containers.txt +242 -0
- package/tree-sitter/test/corpus/control_flow.txt +361 -0
- package/tree-sitter/test/corpus/decorators.txt +64 -0
- package/tree-sitter/test/corpus/existential.txt +102 -0
- package/tree-sitter/test/corpus/functions.txt +293 -0
- package/tree-sitter/test/corpus/imports.txt +117 -0
- package/tree-sitter/test/corpus/literals.txt +135 -0
- package/tree-sitter/test/corpus/operators.txt +296 -0
- package/tree-sitter/test/corpus/statements.txt +189 -0
- package/tree-sitter/test/corpus/strings.txt +90 -0
- package/tree-sitter/test/corpus/subscripts.txt +227 -0
- package/tree-sitter/tree-sitter.json +36 -0
- package/web-repl/env.js +35 -23
- package/web-repl/main.js +8 -8
- package/bin/export +0 -75
- package/bin/web-repl-export +0 -102
- package/tools/cli.js +0 -523
- package/tools/compile.js +0 -184
- package/tools/compiler.js +0 -84
- package/tools/test.js +0 -110
package/src/output/loops.pyj
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# vim:fileencoding=utf-8
|
|
2
2
|
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
-
# globals: regenerate
|
|
4
3
|
from __python__ import hash_literals
|
|
5
4
|
|
|
6
5
|
from ast import AST_BaseCall, AST_SymbolRef, AST_Array, AST_Unary, AST_Number, has_calls, AST_Seq, AST_ListComprehension, is_node_type
|
|
@@ -39,7 +38,7 @@ def is_simple_for_in(self):
|
|
|
39
38
|
# return true if this loop can be simplified into a basic for (i in j) loop
|
|
40
39
|
if is_node_type(self.object, AST_BaseCall)
|
|
41
40
|
and is_node_type(self.object.expression, AST_SymbolRef)
|
|
42
|
-
and self.object.expression.name is "dir" and self.object.args.length is 1:
|
|
41
|
+
and self.object.expression.name is "dir" and self.object.args.args.length is 1:
|
|
43
42
|
return True
|
|
44
43
|
return False
|
|
45
44
|
|
|
@@ -49,13 +48,13 @@ def is_simple_for(self):
|
|
|
49
48
|
is_node_type(self.object.expression, AST_SymbolRef) and
|
|
50
49
|
self.object.expression.name is "range" and
|
|
51
50
|
not (is_node_type(self.init, AST_Array))):
|
|
52
|
-
a = self.object.args
|
|
51
|
+
a = self.object.args.args
|
|
53
52
|
l = a.length
|
|
54
53
|
if l < 3 or (
|
|
55
|
-
is_node_type(a[2], AST_Number) or (
|
|
56
|
-
is_node_type(a[2], AST_Unary) and a[2].operator is '-' and is_node_type(a[2].expression, AST_Number)
|
|
54
|
+
is_node_type(a[2].value, AST_Number) or (
|
|
55
|
+
is_node_type(a[2].value, AST_Unary) and a[2].value.operator is '-' and is_node_type(a[2].value.expression, AST_Number)
|
|
57
56
|
)):
|
|
58
|
-
if (l is 1 and not has_calls(a[0])) or (l > 1 and not has_calls(a[1])):
|
|
57
|
+
if (l is 1 and not has_calls(a[0].value)) or (l > 1 and not has_calls(a[1].value)):
|
|
59
58
|
return True
|
|
60
59
|
return False
|
|
61
60
|
|
|
@@ -65,10 +64,7 @@ def print_for_loop_body(output):
|
|
|
65
64
|
if not (self.simple_for_index or is_simple_for_in(self)):
|
|
66
65
|
# if we're using multiple iterators, unpack them
|
|
67
66
|
output.indent()
|
|
68
|
-
|
|
69
|
-
itervar = "ρσ_Iter" + output.index_counter + "[ρσ_Index" + output.index_counter + "]"
|
|
70
|
-
else:
|
|
71
|
-
itervar = "ρσ_Index" + output.index_counter
|
|
67
|
+
itervar = "ρσ_Index" + output.index_counter
|
|
72
68
|
if is_node_type(self.init, AST_Array):
|
|
73
69
|
flat = self.init.flatten()
|
|
74
70
|
output.assign("ρσ_unpack")
|
|
@@ -112,18 +108,18 @@ def print_for_in(self, output):
|
|
|
112
108
|
if is_simple_for(self):
|
|
113
109
|
# optimize range() into a simple for loop
|
|
114
110
|
increment = None
|
|
115
|
-
args = self.object.args
|
|
111
|
+
args = self.object.args.args
|
|
116
112
|
tmp_ = args.length
|
|
117
113
|
if tmp_ is 1:
|
|
118
114
|
start = 0
|
|
119
|
-
end = args[0]
|
|
115
|
+
end = args[0].value
|
|
120
116
|
elif tmp_ is 2:
|
|
121
|
-
start = args[0]
|
|
122
|
-
end = args[1]
|
|
117
|
+
start = args[0].value
|
|
118
|
+
end = args[1].value
|
|
123
119
|
elif tmp_ is 3:
|
|
124
|
-
start = args[0]
|
|
125
|
-
end = args[1]
|
|
126
|
-
increment = args[2]
|
|
120
|
+
start = args[0].value
|
|
121
|
+
end = args[1].value
|
|
122
|
+
increment = args[2].value
|
|
127
123
|
|
|
128
124
|
self.simple_for_index = idx = 'ρσ_Index' + output.index_counter
|
|
129
125
|
output.index_counter += 1
|
|
@@ -164,43 +160,17 @@ def print_for_in(self, output):
|
|
|
164
160
|
output.space()
|
|
165
161
|
output.print('in')
|
|
166
162
|
output.space()
|
|
167
|
-
self.object.args[0].print(output)
|
|
163
|
+
self.object.args.args[0].value.print(output)
|
|
168
164
|
)
|
|
169
165
|
else:
|
|
170
166
|
# regular loop
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
output.print("for")
|
|
179
|
-
output.space()
|
|
180
|
-
output.with_parens(def():
|
|
181
|
-
output.print("var")
|
|
182
|
-
output.space()
|
|
183
|
-
output.assign("ρσ_Index" + output.index_counter)
|
|
184
|
-
output.print("0")
|
|
185
|
-
output.semicolon()
|
|
186
|
-
output.space()
|
|
187
|
-
output.print("ρσ_Index" + output.index_counter)
|
|
188
|
-
output.space()
|
|
189
|
-
output.print("<")
|
|
190
|
-
output.space()
|
|
191
|
-
output.print("ρσ_Iter" + output.index_counter + ".length")
|
|
192
|
-
output.semicolon()
|
|
193
|
-
output.space()
|
|
194
|
-
output.print("ρσ_Index" + output.index_counter + "++")
|
|
195
|
-
)
|
|
196
|
-
else:
|
|
197
|
-
itervar = "ρσ_Iter" + output.index_counter
|
|
198
|
-
output.assign("var " + itervar)
|
|
199
|
-
write_object()
|
|
200
|
-
output.end_statement()
|
|
201
|
-
init_es6_itervar(output, itervar)
|
|
202
|
-
output.indent()
|
|
203
|
-
output.spaced('for', '(var', 'ρσ_Index' + output.index_counter, 'of', itervar + ')')
|
|
167
|
+
itervar = "ρσ_Iter" + output.index_counter
|
|
168
|
+
output.assign("var " + itervar)
|
|
169
|
+
write_object()
|
|
170
|
+
output.end_statement()
|
|
171
|
+
init_es6_itervar(output, itervar)
|
|
172
|
+
output.indent()
|
|
173
|
+
output.spaced('for', '(var', 'ρσ_Index' + output.index_counter, 'of', itervar + ')')
|
|
204
174
|
|
|
205
175
|
output.space()
|
|
206
176
|
self._do_print_body(output)
|
|
@@ -209,7 +179,6 @@ def print_list_comprehension(self, output):
|
|
|
209
179
|
tname = self.constructor.name.slice(4)
|
|
210
180
|
result_obj = {'ListComprehension':'[]', 'DictComprehension':('Object.create(null)' if self.is_jshash else '{}'), 'SetComprehension':'ρσ_set()'}[tname]
|
|
211
181
|
is_generator = tname is 'GeneratorComprehension'
|
|
212
|
-
es5 = output.options.js_version is 5
|
|
213
182
|
if tname is 'DictComprehension':
|
|
214
183
|
if self.is_pydict:
|
|
215
184
|
result_obj = 'ρσ_dict()'
|
|
@@ -264,8 +233,6 @@ def print_list_comprehension(self, output):
|
|
|
264
233
|
output.with_block(def():
|
|
265
234
|
body_out = output
|
|
266
235
|
if is_generator:
|
|
267
|
-
if es5:
|
|
268
|
-
body_out = OutputStream({'beautify':True})
|
|
269
236
|
body_out.indent()
|
|
270
237
|
body_out.print('function* js_generator()'), body_out.space(), body_out.print('{')
|
|
271
238
|
body_out.newline()
|
|
@@ -273,13 +240,7 @@ def print_list_comprehension(self, output):
|
|
|
273
240
|
output.set_indentation(output.next_indent())
|
|
274
241
|
body_out.indent()
|
|
275
242
|
body_out.assign("var ρσ_Iter")
|
|
276
|
-
|
|
277
|
-
body_out.print("ρσ_Iterable")
|
|
278
|
-
body_out.with_parens(def():
|
|
279
|
-
self.object.print(body_out)
|
|
280
|
-
)
|
|
281
|
-
else:
|
|
282
|
-
self.object.print(body_out)
|
|
243
|
+
self.object.print(body_out)
|
|
283
244
|
|
|
284
245
|
if result_obj:
|
|
285
246
|
body_out.comma()
|
|
@@ -295,34 +256,17 @@ def print_list_comprehension(self, output):
|
|
|
295
256
|
self.init.print(body_out)
|
|
296
257
|
body_out.end_statement()
|
|
297
258
|
|
|
298
|
-
|
|
299
|
-
init_es6_itervar(body_out, 'ρσ_Iter')
|
|
259
|
+
init_es6_itervar(body_out, 'ρσ_Iter')
|
|
300
260
|
body_out.indent()
|
|
301
261
|
body_out.print("for")
|
|
302
262
|
body_out.space()
|
|
303
263
|
body_out.with_parens(def():
|
|
304
|
-
|
|
305
|
-
body_out.print("var")
|
|
306
|
-
body_out.space()
|
|
307
|
-
body_out.assign("ρσ_Index")
|
|
308
|
-
body_out.print("0")
|
|
309
|
-
body_out.semicolon()
|
|
310
|
-
body_out.space()
|
|
311
|
-
body_out.print("ρσ_Index")
|
|
312
|
-
body_out.space()
|
|
313
|
-
body_out.print("<")
|
|
314
|
-
body_out.space()
|
|
315
|
-
body_out.print("ρσ_Iter.length")
|
|
316
|
-
body_out.semicolon()
|
|
317
|
-
body_out.space()
|
|
318
|
-
body_out.print("ρσ_Index++")
|
|
319
|
-
else:
|
|
320
|
-
body_out.spaced('var', 'ρσ_Index', 'of', 'ρσ_Iter')
|
|
264
|
+
body_out.spaced('var', 'ρσ_Index', 'of', 'ρσ_Iter')
|
|
321
265
|
)
|
|
322
266
|
body_out.space()
|
|
323
267
|
body_out.with_block(def():
|
|
324
268
|
body_out.indent()
|
|
325
|
-
itervar = 'ρσ
|
|
269
|
+
itervar = 'ρσ_Index'
|
|
326
270
|
if is_node_type(self.init, AST_Array):
|
|
327
271
|
flat = self.init.flatten()
|
|
328
272
|
body_out.assign("ρσ_unpack")
|
|
@@ -362,12 +306,6 @@ def print_list_comprehension(self, output):
|
|
|
362
306
|
if is_generator:
|
|
363
307
|
output.set_indentation(previous_indentation)
|
|
364
308
|
body_out.newline(), body_out.indent(), body_out.print('}') # end js_generator
|
|
365
|
-
if es5:
|
|
366
|
-
transpiled = regenerate(body_out.get(), output.options.beautify).replace(/regeneratorRuntime.(wrap|mark)/g, 'ρσ_regenerator.regeneratorRuntime.$1')
|
|
367
|
-
if output.options.beautify:
|
|
368
|
-
ci = output.make_indent(0)
|
|
369
|
-
transpiled = [ci + x for x in transpiled.split('\n')].join('\n')
|
|
370
|
-
output.print(transpiled)
|
|
371
309
|
output.newline(), output.indent()
|
|
372
310
|
output.spaced('var', 'result', '=', 'js_generator.call(this)')
|
|
373
311
|
output.end_statement()
|
package/src/output/modules.pyj
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
# vim:fileencoding=utf-8
|
|
2
2
|
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
-
# globals: writefile
|
|
4
3
|
from __python__ import hash_literals
|
|
5
4
|
|
|
6
5
|
from output.statements import declare_vars, display_body
|
|
7
|
-
from output.stream import OutputStream
|
|
8
6
|
from output.utils import create_doctring
|
|
9
7
|
from output.comments import print_comments, output_comments
|
|
10
8
|
from output.functions import set_module_name
|
|
11
|
-
from parse import get_compiler_version
|
|
12
|
-
from utils import cache_file_name
|
|
13
9
|
|
|
14
10
|
|
|
15
11
|
def write_imports(module, output):
|
|
@@ -103,14 +99,10 @@ def prologue(module, output):
|
|
|
103
99
|
output.end_statement()
|
|
104
100
|
output.indent(), output.spaced('var', 'ρσ_cond_temp,', 'ρσ_expr_temp,', 'ρσ_last_exception'), output.end_statement()
|
|
105
101
|
output.indent(), output.spaced('var', 'ρσ_object_counter', '=', '0'), output.end_statement()
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
output.end_statement()
|
|
111
|
-
needs_yield = output.options.js_version < 6 and module.baselib['yield']
|
|
112
|
-
if needs_yield:
|
|
113
|
-
output.dump_yield()
|
|
102
|
+
# Needed for Chrome < 51 and Edge as of August 2016
|
|
103
|
+
output.indent(), output.spaced('if(', 'typeof', 'HTMLCollection', '!==', '"undefined"', '&&', 'typeof', 'Symbol', '===', '"function")',
|
|
104
|
+
'NodeList.prototype[Symbol.iterator]', '=', 'HTMLCollection.prototype[Symbol.iterator]', '=', 'NamedNodeMap.prototype[Symbol.iterator]', '=', 'Array.prototype[Symbol.iterator]')
|
|
105
|
+
output.end_statement()
|
|
114
106
|
# output the baselib
|
|
115
107
|
if not output.options.baselib_plain:
|
|
116
108
|
raise ValueError('The baselib is missing! Remember to set the baselib_plain field on the options for OutputStream')
|
|
@@ -198,41 +190,7 @@ def print_module(self, output):
|
|
|
198
190
|
output.print('"' + self.module_id + '"')
|
|
199
191
|
output.semicolon()
|
|
200
192
|
output.newline()
|
|
201
|
-
|
|
202
|
-
return 'beautify:' + beautify + ' keep_docstrings:' + keep_docstrings + ' js_version:' + js_version
|
|
203
|
-
okey = output_key(output.options.beautify, output.options.keep_docstrings, output.options.js_version)
|
|
204
|
-
if self.is_cached and okey in self.outputs:
|
|
205
|
-
output.print(self.outputs[okey])
|
|
206
|
-
else:
|
|
207
|
-
output_module(output)
|
|
208
|
-
if self.srchash and self.filename:
|
|
209
|
-
cached = {
|
|
210
|
-
'version':get_compiler_version(), 'signature':self.srchash, 'classes': {}, 'baselib':self.baselib,
|
|
211
|
-
'nonlocalvars':self.nonlocalvars, 'imported_module_ids':self.imported_module_ids, 'exports':[],
|
|
212
|
-
'outputs':{}, 'discard_asserts': v'!!output.options.discard_asserts'
|
|
213
|
-
}
|
|
214
|
-
for cname in Object.keys(self.classes):
|
|
215
|
-
cobj = self.classes[cname]
|
|
216
|
-
cached.classes[cname] = {'name':{'name':cobj.name.name}, 'static':cobj.static, 'bound':cobj.bound, 'classvars':cobj.classvars}
|
|
217
|
-
for symdef in self.exports:
|
|
218
|
-
cached.exports.push({'name':symdef.name})
|
|
219
|
-
for beautify in [True, False]:
|
|
220
|
-
for keep_docstrings in [True, False]:
|
|
221
|
-
for js_version in [5, 6]:
|
|
222
|
-
co = OutputStream({
|
|
223
|
-
'beautify':beautify, 'keep_docstrings':keep_docstrings,
|
|
224
|
-
'js_version':js_version, 'private_scope':False,
|
|
225
|
-
'write_name':False, 'discard_asserts':output.options.discard_asserts
|
|
226
|
-
})
|
|
227
|
-
co.with_indent(output.indentation(), def():
|
|
228
|
-
output_module(co)
|
|
229
|
-
)
|
|
230
|
-
raw = co.get()
|
|
231
|
-
cached.outputs[output_key(beautify, keep_docstrings, js_version)] = raw
|
|
232
|
-
try:
|
|
233
|
-
writefile(cache_file_name(self.filename, output.options.module_cache_dir), JSON.stringify(cached, None, '\t'))
|
|
234
|
-
except Error as e:
|
|
235
|
-
console.error('Failed to write output cache file:', self.filename + '-cached', 'with error:', e)
|
|
193
|
+
output_module(output)
|
|
236
194
|
)
|
|
237
195
|
)
|
|
238
196
|
output.print("()")
|
|
@@ -82,7 +82,7 @@ def display_complex_body(node, is_toplevel, output, function_preamble):
|
|
|
82
82
|
output.indent()
|
|
83
83
|
output.print("var")
|
|
84
84
|
output.space()
|
|
85
|
-
output.assign(node.argnames[0])
|
|
85
|
+
output.assign(node.argnames.args[0])
|
|
86
86
|
output.print("this")
|
|
87
87
|
output.semicolon()
|
|
88
88
|
output.newline()
|
package/src/output/stream.pyj
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# vim:fileencoding=utf-8
|
|
2
2
|
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
-
# globals:regenerate
|
|
4
3
|
from __python__ import hash_literals
|
|
5
4
|
|
|
6
5
|
from utils import make_predicate, defaults, repeat_string
|
|
@@ -8,6 +7,16 @@ from tokenizer import is_identifier_char
|
|
|
8
7
|
|
|
9
8
|
DANGEROUS = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
|
|
10
9
|
|
|
10
|
+
# Pre-computed ASCII lookup for identifier characters used in the space-emission
|
|
11
|
+
# hot path. Avoids the full unicode-aware is_identifier_char() for the common case.
|
|
12
|
+
_IDENT_CHARS = v'(function(){var t=new Uint8Array(128),s="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$";for(var i=0;i<s.length;i++)t[s.charCodeAt(i)]=1;return t;})()'
|
|
13
|
+
|
|
14
|
+
def _is_ident_char(ch):
|
|
15
|
+
code = ch.charCodeAt(0)
|
|
16
|
+
if code < 128:
|
|
17
|
+
return v'_IDENT_CHARS[code]'
|
|
18
|
+
return is_identifier_char(ch)
|
|
19
|
+
|
|
11
20
|
|
|
12
21
|
def as_hex(code, sz):
|
|
13
22
|
val = code.toString(16)
|
|
@@ -43,6 +52,7 @@ output_stream_defaults = {
|
|
|
43
52
|
'ie_proof': True,
|
|
44
53
|
'beautify': False,
|
|
45
54
|
'source_map': None,
|
|
55
|
+
'source_map_line_offset': 0,
|
|
46
56
|
'bracketize': False,
|
|
47
57
|
'semicolons': True,
|
|
48
58
|
'comments': False,
|
|
@@ -53,7 +63,7 @@ output_stream_defaults = {
|
|
|
53
63
|
'keep_docstrings': False,
|
|
54
64
|
'discard_asserts': False,
|
|
55
65
|
'module_cache_dir': '',
|
|
56
|
-
'js_version':
|
|
66
|
+
'js_version':6,
|
|
57
67
|
'write_name': True,
|
|
58
68
|
}
|
|
59
69
|
|
|
@@ -65,14 +75,22 @@ class OutputStream:
|
|
|
65
75
|
self.current_col = 0
|
|
66
76
|
self.current_line = 1
|
|
67
77
|
self.current_pos = 0
|
|
68
|
-
self.
|
|
78
|
+
self._fragments = v'[]'
|
|
69
79
|
self.might_need_space = False
|
|
70
80
|
self.might_need_semicolon = False
|
|
71
81
|
self._last = None
|
|
72
|
-
self._stack = []
|
|
82
|
+
self._stack = v'[]'
|
|
73
83
|
self.index_counter = 0
|
|
74
84
|
self.with_counter = 0
|
|
75
85
|
self.try_else_counter = 0
|
|
86
|
+
self._source_map_segments = v'[]' if self.options.source_map else None
|
|
87
|
+
# Indentation string cache: avoids repeat_string() on every indent() call
|
|
88
|
+
self._indent_cache_val = -1
|
|
89
|
+
self._indent_cache_str = ""
|
|
90
|
+
# Install no-op add_mapping on the instance when source maps are disabled,
|
|
91
|
+
# avoiding a null check and array push per node in the hot output walk.
|
|
92
|
+
if not self.options.source_map:
|
|
93
|
+
self.add_mapping = def(node): pass
|
|
76
94
|
|
|
77
95
|
def new_try_else_counter(self):
|
|
78
96
|
self.try_else_counter += 1
|
|
@@ -89,7 +107,13 @@ class OutputStream:
|
|
|
89
107
|
self.print(self.make_name(name))
|
|
90
108
|
|
|
91
109
|
def make_indent(self, back):
|
|
92
|
-
|
|
110
|
+
target = self.options.indent_start + self._indentation - (back or 0) * self.options.indent_level
|
|
111
|
+
if target == self._indent_cache_val:
|
|
112
|
+
return self._indent_cache_str
|
|
113
|
+
s = repeat_string(" ", target)
|
|
114
|
+
self._indent_cache_val = target
|
|
115
|
+
self._indent_cache_str = s
|
|
116
|
+
return s
|
|
93
117
|
|
|
94
118
|
# -----[ beautification/minification ]-----
|
|
95
119
|
def last_char(self):
|
|
@@ -105,11 +129,11 @@ class OutputStream:
|
|
|
105
129
|
if self.might_need_semicolon:
|
|
106
130
|
if (not ch or ";}".indexOf(ch) < 0) and not /[;]$/.test(self._last):
|
|
107
131
|
if self.options.semicolons or require_semi_colon_chars[ch]:
|
|
108
|
-
self.
|
|
132
|
+
self._fragments.push(";")
|
|
109
133
|
self.current_col += 1
|
|
110
134
|
self.current_pos += 1
|
|
111
135
|
else:
|
|
112
|
-
self.
|
|
136
|
+
self._fragments.push("\n")
|
|
113
137
|
self.current_pos += 1
|
|
114
138
|
self.current_line += 1
|
|
115
139
|
self.current_col = 0
|
|
@@ -124,7 +148,7 @@ class OutputStream:
|
|
|
124
148
|
if not self.options.beautify and self.options.preserve_line and self._stack[self._stack.length - 1]:
|
|
125
149
|
target_line = self._stack[self._stack.length - 1].start.line
|
|
126
150
|
while self.current_line < target_line:
|
|
127
|
-
self.
|
|
151
|
+
self._fragments.push("\n")
|
|
128
152
|
self.current_pos += 1
|
|
129
153
|
self.current_line += 1
|
|
130
154
|
self.current_col = 0
|
|
@@ -133,25 +157,27 @@ class OutputStream:
|
|
|
133
157
|
|
|
134
158
|
if self.might_need_space:
|
|
135
159
|
prev = self.last_char()
|
|
136
|
-
if
|
|
160
|
+
if _is_ident_char(prev) and (_is_ident_char(ch) or ch is "\\")
|
|
137
161
|
or /^[\+\-\/]$/.test(ch) and ch is prev:
|
|
138
|
-
self.
|
|
162
|
+
self._fragments.push(" ")
|
|
139
163
|
self.current_col += 1
|
|
140
164
|
self.current_pos += 1
|
|
141
165
|
|
|
142
166
|
self.might_need_space = False
|
|
143
167
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
self.
|
|
147
|
-
if n
|
|
148
|
-
self.current_col +=
|
|
168
|
+
# Fast path: no newlines (the vast majority of tokens).
|
|
169
|
+
# Avoids regex allocation and array creation for single-line fragments.
|
|
170
|
+
self.current_pos += str_.length
|
|
171
|
+
if str_.indexOf('\n') < 0:
|
|
172
|
+
self.current_col += str_.length
|
|
149
173
|
else:
|
|
150
|
-
|
|
174
|
+
a = str_.split('\n')
|
|
175
|
+
n = a.length - 1
|
|
176
|
+
self.current_line += n
|
|
177
|
+
self.current_col = v'a[n].length'
|
|
151
178
|
|
|
152
|
-
self.current_pos += str_.length
|
|
153
179
|
self._last = str_
|
|
154
|
-
self.
|
|
180
|
+
self._fragments.push(str_)
|
|
155
181
|
|
|
156
182
|
def space(self):
|
|
157
183
|
if self.options.beautify:
|
|
@@ -246,20 +272,8 @@ class OutputStream:
|
|
|
246
272
|
if self.options.space_colon:
|
|
247
273
|
self.space()
|
|
248
274
|
|
|
249
|
-
def dump_yield(self):
|
|
250
|
-
self.indent()
|
|
251
|
-
self.spaced('var', 'ρσ_regenerator', '=', '{}')
|
|
252
|
-
self.end_statement()
|
|
253
|
-
code = 'ρσ_regenerator.regeneratorRuntime = ' + regenerate(False, self.options.beautify)
|
|
254
|
-
if self.options.beautify:
|
|
255
|
-
code = code.replace(/\/\/.*$/mg, '\n').replace(/^\s*$/gm, '') # strip comments
|
|
256
|
-
ci = self.make_indent(0)
|
|
257
|
-
code = [ci + x for x in code.split('\n')].join('\n')
|
|
258
|
-
self.print(code + '})(ρσ_regenerator)')
|
|
259
|
-
self.end_statement()
|
|
260
|
-
|
|
261
275
|
def get(self):
|
|
262
|
-
return self.
|
|
276
|
+
return self._fragments.join('')
|
|
263
277
|
toString = get
|
|
264
278
|
|
|
265
279
|
def assign(self, name):
|
|
@@ -304,3 +318,16 @@ class OutputStream:
|
|
|
304
318
|
|
|
305
319
|
def parent(self, n):
|
|
306
320
|
return self._stack[self._stack.length - 2 - (n or 0)]
|
|
321
|
+
|
|
322
|
+
def add_mapping(self, node):
|
|
323
|
+
if self._source_map_segments is not None and node.start and node.start.file:
|
|
324
|
+
self._source_map_segments.push(v'[self.current_line - 1 + self.options.source_map_line_offset, self.current_col, node.start.file, node.start.line - 1, node.start.col]')
|
|
325
|
+
|
|
326
|
+
def add_cached_mappings(self, segments, line_offset):
|
|
327
|
+
if self._source_map_segments is None:
|
|
328
|
+
return
|
|
329
|
+
for seg in segments:
|
|
330
|
+
self._source_map_segments.push(v'[seg[0] + line_offset, seg[1], seg[2], seg[3], seg[4]]')
|
|
331
|
+
|
|
332
|
+
def get_source_map_segments(self):
|
|
333
|
+
return self._source_map_segments
|