rapydscript-ng 0.7.24 → 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.
Files changed (114) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +72 -26
  3. package/bin/package.json +1 -0
  4. package/bin/rapydscript +65 -62
  5. package/editor-plugins/nvim/rapydscript/README.md +184 -0
  6. package/editor-plugins/nvim/rapydscript/bin/rapydscript.so +0 -0
  7. package/editor-plugins/nvim/rapydscript/ftdetect/rapydscript.lua +10 -0
  8. package/editor-plugins/nvim/rapydscript/lua/rapydscript/health.lua +88 -0
  9. package/editor-plugins/nvim/rapydscript/lua/rapydscript/init.lua +279 -0
  10. package/local-agent.md +28 -0
  11. package/package.json +4 -5
  12. package/release/baselib-plain-pretty.js +448 -326
  13. package/release/baselib-plain-ugly.js +3 -3
  14. package/release/compiler.js +2528 -1672
  15. package/release/signatures.json +17 -17
  16. package/src/ast.pyj +73 -25
  17. package/src/baselib-builtins.pyj +2 -2
  18. package/src/baselib-containers.pyj +153 -151
  19. package/src/baselib-internal.pyj +3 -3
  20. package/src/baselib-str.pyj +5 -5
  21. package/src/lib/aes.pyj +1 -1
  22. package/src/lib/encodings.pyj +1 -1
  23. package/src/lib/pythonize.pyj +1 -1
  24. package/src/lib/re.pyj +2 -2
  25. package/src/lib/traceback.pyj +165 -28
  26. package/src/lib/uuid.pyj +1 -1
  27. package/src/output/codegen.pyj +10 -3
  28. package/src/output/functions.pyj +31 -40
  29. package/src/output/literals.pyj +11 -14
  30. package/src/output/loops.pyj +25 -87
  31. package/src/output/modules.pyj +5 -47
  32. package/src/output/statements.pyj +1 -1
  33. package/src/output/stream.pyj +58 -31
  34. package/src/parse.pyj +777 -427
  35. package/src/tokenizer.pyj +16 -4
  36. package/src/utils.pyj +1 -1
  37. package/test/_treeshake_mod.pyj +30 -0
  38. package/test/_treeshake_side_effect.pyj +9 -0
  39. package/test/ast_serialization.pyj +392 -0
  40. package/test/async.pyj +95 -0
  41. package/test/baselib.pyj +1 -2
  42. package/test/embedded_compiler.pyj +57 -0
  43. package/test/fmt.pyj +201 -0
  44. package/test/generic.pyj +7 -3
  45. package/test/imports.pyj +8 -6
  46. package/test/internationalization.pyj +38 -37
  47. package/test/lint.pyj +120 -117
  48. package/test/lsp.pyj +222 -0
  49. package/test/repl.pyj +70 -65
  50. package/test/sourcemaps.pyj +315 -0
  51. package/test/starargs.pyj +46 -39
  52. package/test/traceback.pyj +263 -0
  53. package/test/treeshaking.pyj +181 -0
  54. package/test/web_repl_export.pyj +88 -0
  55. package/tools/ast_serialize.mjs +557 -0
  56. package/tools/cli.mjs +510 -0
  57. package/tools/compile.mjs +201 -0
  58. package/tools/compiler.mjs +127 -0
  59. package/tools/{completer.js → completer.mjs} +6 -6
  60. package/tools/{embedded_compiler.js → embedded_compiler.mjs} +17 -13
  61. package/tools/export.js +109 -56
  62. package/tools/fmt.mjs +735 -0
  63. package/tools/{gettext.js → gettext.mjs} +46 -53
  64. package/tools/{ini.js → ini.mjs} +9 -10
  65. package/tools/{lint.js → lint.mjs} +78 -55
  66. package/tools/lsp.mjs +914 -0
  67. package/tools/lsp_protocol.mjs +259 -0
  68. package/tools/lsp_symbols.mjs +418 -0
  69. package/tools/{msgfmt.js → msgfmt.mjs} +18 -18
  70. package/tools/{repl.js → repl.mjs} +52 -41
  71. package/tools/{self.js → self.mjs} +56 -46
  72. package/tools/sourcemap.mjs +123 -0
  73. package/tools/test.mjs +152 -0
  74. package/tools/treeshake.mjs +400 -0
  75. package/tools/{utils.js → utils.mjs} +26 -23
  76. package/tools/{web_repl.js → web_repl.mjs} +15 -13
  77. package/tools/web_repl_export.mjs +93 -0
  78. package/tree-sitter/README.md +101 -0
  79. package/tree-sitter/grammar.js +992 -0
  80. package/tree-sitter/package.json +43 -0
  81. package/tree-sitter/queries/rapydscript/highlights.scm +232 -0
  82. package/tree-sitter/queries/rapydscript/indents.scm +64 -0
  83. package/tree-sitter/queries/rapydscript/injections.scm +14 -0
  84. package/tree-sitter/queries/rapydscript/locals.scm +108 -0
  85. package/tree-sitter/src/grammar.json +4976 -0
  86. package/tree-sitter/src/node-types.json +2901 -0
  87. package/tree-sitter/src/parser.c +196465 -0
  88. package/tree-sitter/src/scanner.c +294 -0
  89. package/tree-sitter/src/tree_sitter/alloc.h +54 -0
  90. package/tree-sitter/src/tree_sitter/array.h +330 -0
  91. package/tree-sitter/src/tree_sitter/parser.h +286 -0
  92. package/tree-sitter/test/corpus/chaining.txt +99 -0
  93. package/tree-sitter/test/corpus/classes.txt +147 -0
  94. package/tree-sitter/test/corpus/comprehensions.txt +155 -0
  95. package/tree-sitter/test/corpus/containers.txt +242 -0
  96. package/tree-sitter/test/corpus/control_flow.txt +361 -0
  97. package/tree-sitter/test/corpus/decorators.txt +64 -0
  98. package/tree-sitter/test/corpus/existential.txt +102 -0
  99. package/tree-sitter/test/corpus/functions.txt +293 -0
  100. package/tree-sitter/test/corpus/imports.txt +117 -0
  101. package/tree-sitter/test/corpus/literals.txt +135 -0
  102. package/tree-sitter/test/corpus/operators.txt +296 -0
  103. package/tree-sitter/test/corpus/statements.txt +189 -0
  104. package/tree-sitter/test/corpus/strings.txt +90 -0
  105. package/tree-sitter/test/corpus/subscripts.txt +227 -0
  106. package/tree-sitter/tree-sitter.json +36 -0
  107. package/web-repl/env.js +35 -23
  108. package/web-repl/main.js +8 -8
  109. package/bin/export +0 -75
  110. package/bin/web-repl-export +0 -102
  111. package/tools/cli.js +0 -523
  112. package/tools/compile.js +0 -184
  113. package/tools/compiler.js +0 -84
  114. package/tools/test.js +0 -110
@@ -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
- if output.options.js_version is 5:
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
- if output.options.js_version is 5:
172
- output.assign("var ρσ_Iter" + output.index_counter)
173
- output.print("ρσ_Iterable")
174
- output.with_parens(write_object)
175
- output.semicolon()
176
- output.newline()
177
- output.indent()
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
- if es5:
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
- if not es5:
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
- if es5:
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 = 'ρσ_Iter[ρσ_Index]' if es5 else 'ρσ_Index'
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()
@@ -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
- if output.options.js_version > 5:
107
- # Needed for Chrome < 51 and Edge as of August 2016
108
- output.indent(), output.spaced('if(', 'typeof', 'HTMLCollection', '!==', '"undefined"', '&&', 'typeof', 'Symbol', '===', '"function")',
109
- 'NodeList.prototype[Symbol.iterator]', '=', 'HTMLCollection.prototype[Symbol.iterator]', '=', 'NamedNodeMap.prototype[Symbol.iterator]', '=', 'Array.prototype[Symbol.iterator]')
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
- def output_key(beautify, keep_docstrings, js_version):
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()
@@ -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':5,
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.OUTPUT = ""
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
- return repeat_string(" ", self.options.indent_start + self._indentation - back * self.options.indent_level)
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.OUTPUT += ";"
132
+ self._fragments.push(";")
109
133
  self.current_col += 1
110
134
  self.current_pos += 1
111
135
  else:
112
- self.OUTPUT += "\n"
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.OUTPUT += "\n"
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 is_identifier_char(prev) and (is_identifier_char(ch) or ch is "\\")
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.OUTPUT += " "
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
- a = str_.split(/\r?\n/)
145
- n = a.length - 1
146
- self.current_line += n
147
- if n is 0:
148
- self.current_col += a[n].length
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
- self.current_col = a[n].length
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.OUTPUT += str_
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.OUTPUT
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