rapydscript-ng 0.8.2 → 0.8.4
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 +17 -0
- package/bin/build.ts +29 -0
- package/local-agent.md +4 -0
- package/package.json +1 -1
- package/release/baselib-plain-pretty.js +85 -61
- package/release/baselib-plain-ugly.js +3 -3
- package/release/compiler.js +9661 -9540
- package/release/signatures.json +26 -26
- package/src/ast.pyj +169 -64
- package/src/baselib-builtins.pyj +35 -14
- package/src/baselib-containers.pyj +70 -40
- package/src/baselib-internal.pyj +20 -8
- package/src/baselib-itertools.pyj +6 -2
- package/src/baselib-str.pyj +74 -28
- package/src/errors.pyj +4 -1
- package/src/lib/aes.pyj +664 -35
- package/src/lib/elementmaker.pyj +105 -13
- package/src/lib/encodings.pyj +31 -7
- package/src/lib/gettext.pyj +6 -3
- package/src/lib/math.pyj +38 -22
- package/src/lib/pythonize.pyj +5 -3
- package/src/lib/random.pyj +13 -5
- package/src/lib/re.pyj +81 -18
- package/src/lib/traceback.pyj +42 -10
- package/src/lib/uuid.pyj +2 -1
- package/src/output/classes.pyj +70 -26
- package/src/output/codegen.pyj +92 -20
- package/src/output/comments.pyj +11 -4
- package/src/output/exceptions.pyj +17 -4
- package/src/output/functions.pyj +145 -26
- package/src/output/literals.pyj +7 -2
- package/src/output/loops.pyj +79 -23
- package/src/output/modules.pyj +41 -12
- package/src/output/operators.pyj +154 -31
- package/src/output/statements.pyj +38 -10
- package/src/output/stream.pyj +43 -12
- package/src/output/utils.pyj +10 -3
- package/src/parse.pyj +740 -259
- package/src/string_interpolation.pyj +4 -1
- package/src/tokenizer.pyj +314 -57
- package/src/unicode_aliases.pyj +4 -2
- package/src/utils.pyj +19 -5
- package/test/functions.pyj +8 -0
- package/test/generic.pyj +9 -0
- package/test/lsp.pyj +16 -0
- package/test/str.pyj +10 -0
- package/tools/cli.mjs +4 -3
- package/tools/compile.mjs +9 -3
- package/tools/compiler.mjs +0 -6
- package/tools/fmt.mjs +41 -2
- package/tools/lint-worker.mjs +107 -0
- package/tools/lint.mjs +134 -8
- package/tools/lsp.mjs +11 -1
- package/tree-sitter/grammar.js +27 -6
- package/tree-sitter/queries/highlights.scm +10 -0
- package/tree-sitter/src/grammar.json +130 -5
- package/tree-sitter/src/node-types.json +73 -0
- package/tree-sitter/src/parser.c +119589 -114993
- package/tree-sitter/src/scanner.c +275 -17
- package/tree-sitter/test/corpus/strings.txt +41 -5
package/src/output/operators.pyj
CHANGED
|
@@ -26,11 +26,18 @@ def print_getattr(self, output, skip_expression): # AST_Dot
|
|
|
26
26
|
def print_getitem(self, output): # AST_Sub
|
|
27
27
|
expr = self.expression
|
|
28
28
|
prop = self.property
|
|
29
|
-
if (
|
|
29
|
+
if (
|
|
30
|
+
is_node_type(prop, AST_Number) or is_node_type(prop, AST_String)
|
|
31
|
+
or (is_node_type(prop, AST_SymbolRef) and prop.name
|
|
32
|
+
and prop.name.startsWith('ρσ_'))
|
|
33
|
+
):
|
|
30
34
|
expr.print(output)
|
|
31
35
|
output.print('['), prop.print(output), output.print(']')
|
|
32
36
|
return
|
|
33
|
-
is_negative_number =
|
|
37
|
+
is_negative_number = (
|
|
38
|
+
is_node_type(prop, AST_Unary) and prop.operator is '-'
|
|
39
|
+
and is_node_type(prop.expression, AST_Number)
|
|
40
|
+
)
|
|
34
41
|
is_repeatable = is_node_type(expr, AST_SymbolRef)
|
|
35
42
|
if is_repeatable:
|
|
36
43
|
expr.print(output)
|
|
@@ -39,17 +46,27 @@ def print_getitem(self, output): # AST_Sub
|
|
|
39
46
|
expr = {'print': def (): output.print('ρσ_expr_temp');}
|
|
40
47
|
|
|
41
48
|
if is_negative_number:
|
|
42
|
-
output.print('['), expr.print(output)
|
|
49
|
+
output.print('['), expr.print(output)
|
|
50
|
+
output.print('.length'), prop.print(output)
|
|
51
|
+
output.print(']')
|
|
43
52
|
return
|
|
44
53
|
is_repeatable = is_node_type(prop, AST_SymbolRef)
|
|
45
54
|
# We have to check the type of the property because if it is a Symbol, it
|
|
46
55
|
# will raise a TypeError with the < operator.
|
|
47
56
|
if is_repeatable:
|
|
48
57
|
output.spaced('[(typeof', prop, '===', '"number"', '&&', prop)
|
|
49
|
-
output.spaced(
|
|
58
|
+
output.spaced(
|
|
59
|
+
'',
|
|
60
|
+
'<',
|
|
61
|
+
'0)',
|
|
62
|
+
'?',
|
|
63
|
+
expr
|
|
64
|
+
), output.spaced('.length', '+', prop, ':', prop)
|
|
50
65
|
output.print(']')
|
|
51
66
|
else:
|
|
52
|
-
output.print('[ρσ_bound_index(')
|
|
67
|
+
output.print('[ρσ_bound_index(')
|
|
68
|
+
prop.print(output), output.comma(), expr.print(output)
|
|
69
|
+
output.print(')]')
|
|
53
70
|
|
|
54
71
|
|
|
55
72
|
def print_rich_getitem(self, output): # AST_ItemAccess
|
|
@@ -74,7 +91,8 @@ def print_rich_getitem(self, output): # AST_ItemAccess
|
|
|
74
91
|
def print_splice_assignment(self, output): # AST_Splice
|
|
75
92
|
# splice assignment via pythonic array[start:end]
|
|
76
93
|
output.print('ρσ_splice(')
|
|
77
|
-
self.expression.print(output), output.comma()
|
|
94
|
+
self.expression.print(output), output.comma()
|
|
95
|
+
self.assignment.print(output), output.comma()
|
|
78
96
|
self.property.print(output) if self.property else output.print('0')
|
|
79
97
|
if self.property2:
|
|
80
98
|
output.comma()
|
|
@@ -86,7 +104,9 @@ def print_delete(self, output):
|
|
|
86
104
|
if is_node_type(self, AST_Symbol):
|
|
87
105
|
output.assign(self), output.print('undefined')
|
|
88
106
|
elif is_node_type(self, AST_Sub) or is_node_type(self, AST_ItemAccess):
|
|
89
|
-
output.print('ρσ_delitem(')
|
|
107
|
+
output.print('ρσ_delitem(')
|
|
108
|
+
self.expression.print(output), output.comma()
|
|
109
|
+
self.property.print(output), output.print(')')
|
|
90
110
|
else:
|
|
91
111
|
output.spaced('delete', self)
|
|
92
112
|
|
|
@@ -122,28 +142,61 @@ def write_instanceof(left, right, output):
|
|
|
122
142
|
do_many(right.elements)
|
|
123
143
|
else:
|
|
124
144
|
output.print('ρσ_instanceof(')
|
|
125
|
-
left.print(output), output.comma()
|
|
145
|
+
left.print(output), output.comma()
|
|
146
|
+
right.print(output), output.print(')')
|
|
126
147
|
|
|
127
148
|
|
|
128
149
|
def write_smart_equality(self, output):
|
|
129
150
|
def is_ok(x):
|
|
130
151
|
return not (
|
|
131
|
-
is_node_type(x, AST_Array) or is_node_type(x, AST_Set)
|
|
132
|
-
|
|
152
|
+
is_node_type(x, AST_Array) or is_node_type(x, AST_Set)
|
|
153
|
+
or is_node_type(x, AST_Object) or is_node_type(x, AST_Statement)
|
|
154
|
+
or is_node_type(x, AST_Binary)
|
|
155
|
+
or is_node_type(x, AST_Conditional)
|
|
133
156
|
or is_node_type(x, AST_BaseCall)
|
|
134
157
|
)
|
|
135
158
|
if is_ok(self.left) and is_ok(self.right):
|
|
136
159
|
if self.operator is '==':
|
|
137
160
|
output.print('(')
|
|
138
|
-
output.spaced(
|
|
139
|
-
|
|
161
|
+
output.spaced(
|
|
162
|
+
self.left,
|
|
163
|
+
'===',
|
|
164
|
+
self.right,
|
|
165
|
+
'||',
|
|
166
|
+
'typeof',
|
|
167
|
+
self.left,
|
|
168
|
+
'===',
|
|
169
|
+
'"object"',
|
|
170
|
+
'&&',
|
|
171
|
+
'ρσ_equals('
|
|
172
|
+
)
|
|
173
|
+
self.left.print(output), output.print(',')
|
|
174
|
+
output.space(), self.right.print(output)
|
|
175
|
+
output.print('))')
|
|
140
176
|
else:
|
|
141
177
|
output.print('(')
|
|
142
|
-
output.spaced(
|
|
143
|
-
|
|
178
|
+
output.spaced(
|
|
179
|
+
self.left,
|
|
180
|
+
'!==',
|
|
181
|
+
self.right,
|
|
182
|
+
'&&',
|
|
183
|
+
'(typeof',
|
|
184
|
+
self.left,
|
|
185
|
+
'!==',
|
|
186
|
+
'"object"',
|
|
187
|
+
'||',
|
|
188
|
+
'ρσ_not_equals('
|
|
189
|
+
)
|
|
190
|
+
self.left.print(output), output.print(',')
|
|
191
|
+
output.space(), self.right.print(output)
|
|
192
|
+
output.print(')))')
|
|
144
193
|
else:
|
|
145
|
-
output.print(
|
|
146
|
-
|
|
194
|
+
output.print(
|
|
195
|
+
'ρσ_' + ('equals(' if self.operator is '==' else 'not_equals(')
|
|
196
|
+
)
|
|
197
|
+
self.left.print(output), output.print(',')
|
|
198
|
+
output.space(), self.right.print(output)
|
|
199
|
+
output.print(')')
|
|
147
200
|
|
|
148
201
|
|
|
149
202
|
comparators = {
|
|
@@ -167,7 +220,10 @@ def print_binary_op(self, output):
|
|
|
167
220
|
output.comma()
|
|
168
221
|
self.right.print(output)
|
|
169
222
|
)
|
|
170
|
-
elif comparators[self.operator] and is_node_type(
|
|
223
|
+
elif comparators[self.operator] and is_node_type(
|
|
224
|
+
self.left,
|
|
225
|
+
AST_Binary
|
|
226
|
+
) and comparators[self.left.operator]:
|
|
171
227
|
# A chained comparison such as a < b < c
|
|
172
228
|
if is_node_type(self.left.right, AST_Symbol):
|
|
173
229
|
# left side compares against a regular variable,
|
|
@@ -210,15 +266,22 @@ def print_binary_op(self, output):
|
|
|
210
266
|
left = self.left.expression
|
|
211
267
|
output.print(self.left.operator)
|
|
212
268
|
if output.options.js_version > 6:
|
|
213
|
-
output.print('(('), left.print(output), output.spaced(
|
|
269
|
+
output.print('(('), left.print(output), output.spaced(
|
|
270
|
+
')',
|
|
271
|
+
'**',
|
|
272
|
+
'('
|
|
273
|
+
), self.right.print(output), output.print('))')
|
|
214
274
|
else:
|
|
215
|
-
output.print('Math.pow('), left.print(output)
|
|
275
|
+
output.print('Math.pow('), left.print(output)
|
|
276
|
+
output.comma(), self.right.print(output)
|
|
277
|
+
output.print(')')
|
|
216
278
|
elif self.operator is '==' or self.operator is '!=':
|
|
217
279
|
write_smart_equality(self, output)
|
|
218
280
|
elif self.operator is 'instanceof':
|
|
219
281
|
write_instanceof(self.left, self.right, output)
|
|
220
282
|
elif self.operator is '*' and is_node_type(self.left, AST_String):
|
|
221
|
-
self.left.print(output), output.print('.repeat(')
|
|
283
|
+
self.left.print(output), output.print('.repeat(')
|
|
284
|
+
self.right.print(output), output.print(')')
|
|
222
285
|
elif self.operator is '===' or self.operator is '!==':
|
|
223
286
|
nan_check = None
|
|
224
287
|
if is_node_type(self.right, AST_Symbol) and self.right.name is 'NaN':
|
|
@@ -228,7 +291,11 @@ def print_binary_op(self, output):
|
|
|
228
291
|
if nan_check is not None:
|
|
229
292
|
# We use the fact that NaN is the only object that is not equal to
|
|
230
293
|
# itself
|
|
231
|
-
output.spaced(
|
|
294
|
+
output.spaced(
|
|
295
|
+
nan_check,
|
|
296
|
+
'!==' if self.operator is '===' else '===',
|
|
297
|
+
nan_check
|
|
298
|
+
)
|
|
232
299
|
else:
|
|
233
300
|
output.spaced(self.left, self.operator, self.right)
|
|
234
301
|
else:
|
|
@@ -238,20 +305,54 @@ after_map = {'.': 'd', '(': 'c', '[': 'd', 'g': 'g', 'null': 'n'}
|
|
|
238
305
|
|
|
239
306
|
|
|
240
307
|
def print_existential(self, output):
|
|
241
|
-
key =
|
|
308
|
+
key = (
|
|
309
|
+
after_map[self.after]
|
|
310
|
+
if self.after is None or jstype(self.after) is 'string' else 'e'
|
|
311
|
+
)
|
|
242
312
|
if is_node_type(self.expression, AST_SymbolRef):
|
|
243
313
|
if key is 'n':
|
|
244
|
-
output.spaced(
|
|
314
|
+
output.spaced(
|
|
315
|
+
'(typeof',
|
|
316
|
+
self.expression,
|
|
317
|
+
'!==',
|
|
318
|
+
'"undefined"',
|
|
319
|
+
'&&',
|
|
320
|
+
self.expression,
|
|
321
|
+
'!==',
|
|
322
|
+
'null)'
|
|
323
|
+
)
|
|
245
324
|
return
|
|
246
325
|
if key is 'c':
|
|
247
|
-
output.spaced(
|
|
326
|
+
output.spaced(
|
|
327
|
+
'(typeof',
|
|
328
|
+
self.expression,
|
|
329
|
+
'===',
|
|
330
|
+
'"function"',
|
|
331
|
+
'?',
|
|
332
|
+
self.expression,
|
|
333
|
+
':',
|
|
334
|
+
'(function(){return undefined;}))'
|
|
335
|
+
)
|
|
248
336
|
return
|
|
249
337
|
after = self.after
|
|
250
338
|
if key is 'd':
|
|
251
339
|
after = 'Object.create(null)'
|
|
252
340
|
elif key is 'g':
|
|
253
341
|
after = '{__getitem__:function(){return undefined;}}'
|
|
254
|
-
output.spaced(
|
|
342
|
+
output.spaced(
|
|
343
|
+
'(typeof',
|
|
344
|
+
self.expression,
|
|
345
|
+
'!==',
|
|
346
|
+
'"undefined"',
|
|
347
|
+
'&&',
|
|
348
|
+
self.expression,
|
|
349
|
+
'!==',
|
|
350
|
+
'null',
|
|
351
|
+
'?',
|
|
352
|
+
self.expression,
|
|
353
|
+
':',
|
|
354
|
+
after
|
|
355
|
+
)
|
|
255
356
|
output.print(')')
|
|
256
357
|
return
|
|
257
358
|
output.print('ρσ_exists.' + key + '(')
|
|
@@ -282,9 +383,13 @@ def print_assignment(self, output):
|
|
|
282
383
|
self.right.print(output)
|
|
283
384
|
if is_node_type(left, AST_Array):
|
|
284
385
|
output.end_statement()
|
|
285
|
-
if not is_node_type(
|
|
386
|
+
if not is_node_type(
|
|
387
|
+
self.right,
|
|
388
|
+
AST_Seq
|
|
389
|
+
) and not is_node_type(self.right, AST_Array):
|
|
286
390
|
output.assign('ρσ_unpack')
|
|
287
|
-
output.print('ρσ_unpack_asarray(' + flat.length)
|
|
391
|
+
output.print('ρσ_unpack_asarray(' + flat.length)
|
|
392
|
+
output.comma(), output.print('ρσ_unpack)')
|
|
288
393
|
output.end_statement()
|
|
289
394
|
unpack_tuple(flat, output, True)
|
|
290
395
|
|
|
@@ -305,15 +410,31 @@ def print_assign(self, output):
|
|
|
305
410
|
left_hand_sides, rhs = self.traverse_chain()
|
|
306
411
|
is_compound_assign = False
|
|
307
412
|
for lhs in left_hand_sides:
|
|
308
|
-
if
|
|
413
|
+
if (
|
|
414
|
+
is_node_type(lhs, AST_Seq)
|
|
415
|
+
or is_node_type(lhs, AST_Array)
|
|
416
|
+
or is_node_type(lhs, AST_ItemAccess)
|
|
417
|
+
):
|
|
309
418
|
is_compound_assign = True
|
|
310
419
|
break
|
|
311
420
|
if is_compound_assign:
|
|
312
421
|
temp_rhs = new AST_SymbolRef({'name': 'ρσ_chain_assign_temp'})
|
|
313
|
-
print_assignment(
|
|
422
|
+
print_assignment(
|
|
423
|
+
new AST_Assign({
|
|
424
|
+
'left': temp_rhs, 'operator': '=', 'right': rhs
|
|
425
|
+
}),
|
|
426
|
+
output
|
|
427
|
+
)
|
|
314
428
|
for lhs in left_hand_sides:
|
|
315
429
|
output.end_statement(), output.indent()
|
|
316
|
-
print_assignment(
|
|
430
|
+
print_assignment(
|
|
431
|
+
new AST_Assign({
|
|
432
|
+
'left': lhs,
|
|
433
|
+
'right': temp_rhs,
|
|
434
|
+
'operator': self.operator
|
|
435
|
+
}),
|
|
436
|
+
output
|
|
437
|
+
)
|
|
317
438
|
else:
|
|
318
439
|
for lhs in left_hand_sides:
|
|
319
440
|
output.spaced(lhs, '=', '')
|
|
@@ -323,7 +444,9 @@ def print_assign(self, output):
|
|
|
323
444
|
|
|
324
445
|
|
|
325
446
|
def print_conditional(self, output, condition, consequent, alternative):
|
|
326
|
-
condition
|
|
447
|
+
condition = self.condition
|
|
448
|
+
consequent = self.consequent
|
|
449
|
+
alternative = self.alternative
|
|
327
450
|
output.with_parens(def (): condition.print(output);)
|
|
328
451
|
output.space()
|
|
329
452
|
output.print('?')
|
|
@@ -70,7 +70,8 @@ def declare_vars(vars, output):
|
|
|
70
70
|
def display_body(body, is_toplevel, output):
|
|
71
71
|
last = body.length - 1
|
|
72
72
|
for i, stmt in enumerate(body):
|
|
73
|
-
if not (is_node_type(stmt, AST_EmptyStatement))
|
|
73
|
+
if (not (is_node_type(stmt, AST_EmptyStatement))
|
|
74
|
+
and not (is_node_type(stmt, AST_Definitions))):
|
|
74
75
|
output.indent()
|
|
75
76
|
stmt.print(output)
|
|
76
77
|
if not (i is last and is_toplevel):
|
|
@@ -134,7 +135,9 @@ def print_bracketed(node, output, complex, function_preamble, before, after):
|
|
|
134
135
|
|
|
135
136
|
def print_with(self, output):
|
|
136
137
|
exits = v'[]'
|
|
137
|
-
output.assign('ρσ_with_exception')
|
|
138
|
+
output.assign('ρσ_with_exception')
|
|
139
|
+
output.print('undefined')
|
|
140
|
+
output.end_statement()
|
|
138
141
|
for clause in self.clauses:
|
|
139
142
|
output.with_counter += 1
|
|
140
143
|
clause_name = 'ρσ_with_clause_' + output.with_counter
|
|
@@ -155,29 +158,54 @@ def print_with(self, output):
|
|
|
155
158
|
)
|
|
156
159
|
output.space(), output.print('catch(e)')
|
|
157
160
|
output.with_block(def ():
|
|
158
|
-
output.indent()
|
|
161
|
+
output.indent()
|
|
162
|
+
output.assign('ρσ_with_exception')
|
|
163
|
+
output.print('e')
|
|
164
|
+
output.end_statement()
|
|
165
|
+
)
|
|
166
|
+
output.newline(), output.indent(), output.spaced(
|
|
167
|
+
'if',
|
|
168
|
+
'(ρσ_with_exception',
|
|
169
|
+
'===',
|
|
170
|
+
'undefined)'
|
|
159
171
|
)
|
|
160
|
-
output.newline(), output.indent(), output.spaced('if', '(ρσ_with_exception', '===', 'undefined)')
|
|
161
172
|
output.with_block(def ():
|
|
162
173
|
for clause in exits:
|
|
163
|
-
output.indent()
|
|
174
|
+
output.indent()
|
|
175
|
+
output.print(clause + '.__exit__()')
|
|
176
|
+
output.end_statement()
|
|
164
177
|
)
|
|
165
178
|
output.space(), output.print('else'), output.space()
|
|
166
179
|
output.with_block(def ():
|
|
167
|
-
output.indent()
|
|
180
|
+
output.indent()
|
|
181
|
+
output.assign('ρσ_with_suppress')
|
|
182
|
+
output.print('false')
|
|
183
|
+
output.end_statement()
|
|
168
184
|
for clause in exits:
|
|
169
185
|
output.indent()
|
|
170
|
-
output.spaced(
|
|
171
|
-
|
|
186
|
+
output.spaced(
|
|
187
|
+
'ρσ_with_suppress', '|=',
|
|
188
|
+
'ρσ_bool(' + clause
|
|
189
|
+
+ '.__exit__(ρσ_with_exception.constructor,',
|
|
190
|
+
'ρσ_with_exception,',
|
|
191
|
+
'ρσ_with_exception.stack))'
|
|
192
|
+
)
|
|
172
193
|
output.end_statement()
|
|
173
|
-
output.indent()
|
|
194
|
+
output.indent()
|
|
195
|
+
output.spaced('if', '(!ρσ_with_suppress)', 'throw ρσ_with_exception')
|
|
196
|
+
output.end_statement()
|
|
174
197
|
)
|
|
175
198
|
|
|
176
199
|
|
|
177
200
|
def print_assert(self, output):
|
|
178
201
|
if output.options.discard_asserts:
|
|
179
202
|
return
|
|
180
|
-
output.spaced(
|
|
203
|
+
output.spaced(
|
|
204
|
+
'if',
|
|
205
|
+
'(!('
|
|
206
|
+
), self.condition.print(output), output.spaced(
|
|
207
|
+
'))', 'throw new AssertionError'
|
|
208
|
+
)
|
|
181
209
|
if self.message:
|
|
182
210
|
output.print('(')
|
|
183
211
|
self.message.print(output)
|
package/src/output/stream.pyj
CHANGED
|
@@ -5,11 +5,24 @@ from __python__ import hash_literals
|
|
|
5
5
|
from tokenizer import is_identifier_char
|
|
6
6
|
from utils import make_predicate, defaults, repeat_string
|
|
7
7
|
|
|
8
|
-
DANGEROUS =
|
|
8
|
+
DANGEROUS = RegExp(
|
|
9
|
+
'[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5' +
|
|
10
|
+
'\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f' +
|
|
11
|
+
'\\ufeff\\ufff0-\\uffff]', 'g'
|
|
12
|
+
)
|
|
13
|
+
|
|
9
14
|
|
|
10
15
|
# 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
|
|
12
|
-
|
|
16
|
+
# hot path. Avoids the full unicode-aware is_identifier_char() for the
|
|
17
|
+
# common case.
|
|
18
|
+
def _make_ident_chars():
|
|
19
|
+
t = v'new Uint8Array(128)'
|
|
20
|
+
s = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'
|
|
21
|
+
for i in range(s.length):
|
|
22
|
+
t[s.charCodeAt(i)] = 1
|
|
23
|
+
return t
|
|
24
|
+
|
|
25
|
+
_IDENT_CHARS = _make_ident_chars()
|
|
13
26
|
|
|
14
27
|
|
|
15
28
|
def _is_ident_char(ch):
|
|
@@ -85,11 +98,13 @@ class OutputStream:
|
|
|
85
98
|
self.with_counter = 0
|
|
86
99
|
self.try_else_counter = 0
|
|
87
100
|
self._source_map_segments = v'[]' if self.options.source_map else None
|
|
88
|
-
# Indentation string cache: avoids repeat_string() on every
|
|
101
|
+
# Indentation string cache: avoids repeat_string() on every
|
|
102
|
+
# indent() call
|
|
89
103
|
self._indent_cache_val = -1
|
|
90
104
|
self._indent_cache_str = ''
|
|
91
|
-
# Install no-op add_mapping on the instance when source maps are
|
|
92
|
-
# avoiding a null check and array push per node in the
|
|
105
|
+
# Install no-op add_mapping on the instance when source maps are
|
|
106
|
+
# disabled, avoiding a null check and array push per node in the
|
|
107
|
+
# hot output walk.
|
|
93
108
|
if not self.options.source_map:
|
|
94
109
|
self.add_mapping = def (node): pass
|
|
95
110
|
|
|
@@ -108,7 +123,10 @@ class OutputStream:
|
|
|
108
123
|
self.print(self.make_name(name))
|
|
109
124
|
|
|
110
125
|
def make_indent(self, back):
|
|
111
|
-
target =
|
|
126
|
+
target = (
|
|
127
|
+
self.options.indent_start + self._indentation -
|
|
128
|
+
(back or 0) * self.options.indent_level
|
|
129
|
+
)
|
|
112
130
|
if target == self._indent_cache_val:
|
|
113
131
|
return self._indent_cache_str
|
|
114
132
|
s = repeat_string(' ', target)
|
|
@@ -121,7 +139,8 @@ class OutputStream:
|
|
|
121
139
|
return self._last.charAt(self._last.length - 1)
|
|
122
140
|
|
|
123
141
|
def maybe_newline(self):
|
|
124
|
-
if self.options.max_line_len and
|
|
142
|
+
if (self.options.max_line_len and
|
|
143
|
+
self.current_col > self.options.max_line_len):
|
|
125
144
|
self.print('\n')
|
|
126
145
|
|
|
127
146
|
def print(self, str_):
|
|
@@ -145,7 +164,9 @@ class OutputStream:
|
|
|
145
164
|
self.might_need_semicolon = False
|
|
146
165
|
self.maybe_newline()
|
|
147
166
|
|
|
148
|
-
if not self.options.beautify and
|
|
167
|
+
if (not self.options.beautify and
|
|
168
|
+
self.options.preserve_line and
|
|
169
|
+
self._stack[self._stack.length - 1]):
|
|
149
170
|
target_line = self._stack[self._stack.length - 1].start.line
|
|
150
171
|
while self.current_line < target_line:
|
|
151
172
|
self._fragments.push('\n')
|
|
@@ -319,14 +340,24 @@ class OutputStream:
|
|
|
319
340
|
return self._stack[self._stack.length - 2 - (n or 0)]
|
|
320
341
|
|
|
321
342
|
def add_mapping(self, node):
|
|
322
|
-
if self._source_map_segments is not None and
|
|
323
|
-
|
|
343
|
+
if (self._source_map_segments is not None and
|
|
344
|
+
node.start and node.start.file):
|
|
345
|
+
self._source_map_segments.push([
|
|
346
|
+
self.current_line - 1 +
|
|
347
|
+
self.options.source_map_line_offset,
|
|
348
|
+
self.current_col,
|
|
349
|
+
node.start.file,
|
|
350
|
+
node.start.line - 1,
|
|
351
|
+
node.start.col
|
|
352
|
+
])
|
|
324
353
|
|
|
325
354
|
def add_cached_mappings(self, segments, line_offset):
|
|
326
355
|
if self._source_map_segments is None:
|
|
327
356
|
return
|
|
328
357
|
for seg in segments:
|
|
329
|
-
self._source_map_segments.push(
|
|
358
|
+
self._source_map_segments.push(
|
|
359
|
+
v'[seg[0] + line_offset, seg[1], seg[2], seg[3], seg[4]]'
|
|
360
|
+
)
|
|
330
361
|
|
|
331
362
|
def get_source_map_segments(self):
|
|
332
363
|
return self._source_map_segments
|
package/src/output/utils.pyj
CHANGED
|
@@ -25,14 +25,18 @@ def make_num(num):
|
|
|
25
25
|
a.push('0x' + num.toString(16).toLowerCase(), # probably pointless
|
|
26
26
|
'0' + num.toString(8))
|
|
27
27
|
else:
|
|
28
|
-
|
|
28
|
+
# probably pointless
|
|
29
|
+
a.push('-0x' + (-num).toString(16).toLowerCase(),
|
|
29
30
|
'-0' + (-num).toString(8))
|
|
30
31
|
|
|
31
32
|
if m = /^(.*?)(0+)$/.exec(num):
|
|
32
33
|
a.push(m[1] + 'e' + m[2].length)
|
|
33
34
|
|
|
34
35
|
elif m = /^0?\.(0+)(.*)$/.exec(num):
|
|
35
|
-
a.push(
|
|
36
|
+
a.push(
|
|
37
|
+
m[2] + 'e-' + (m[1].length + m[2].length),
|
|
38
|
+
str_.substr(str_.indexOf('.'))
|
|
39
|
+
)
|
|
36
40
|
|
|
37
41
|
return best_of(a)
|
|
38
42
|
|
|
@@ -65,7 +69,10 @@ def create_doctring(docstrings):
|
|
|
65
69
|
lines.push(v'["", ""]')
|
|
66
70
|
else:
|
|
67
71
|
leading_whitespace = leading_whitespace.replace(/\t/g, ' ')
|
|
68
|
-
if leading_whitespace and (
|
|
72
|
+
if leading_whitespace and (
|
|
73
|
+
not min_leading_whitespace or
|
|
74
|
+
leading_whitespace.length < min_leading_whitespace.length
|
|
75
|
+
):
|
|
69
76
|
min_leading_whitespace = leading_whitespace
|
|
70
77
|
lines.push(v'[leading_whitespace, line]')
|
|
71
78
|
for lw, l in lines:
|