rapydscript-ns 0.8.4 → 0.9.1
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/.agignore +1 -1
- package/.github/workflows/ci.yml +38 -38
- package/=template.pyj +5 -5
- package/CHANGELOG.md +26 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/README.md +716 -169
- package/TODO.md +7 -2
- package/add-toc-to-readme +2 -2
- package/bin/export +75 -75
- package/bin/rapydscript +70 -70
- package/bin/web-repl-export +102 -102
- package/build +2 -2
- package/language-service/index.js +36 -27
- package/package.json +1 -1
- package/publish.py +37 -37
- package/release/baselib-plain-pretty.js +2358 -168
- package/release/baselib-plain-ugly.js +73 -3
- package/release/compiler.js +6283 -3093
- package/release/signatures.json +31 -30
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/ast.pyj +1 -0
- package/src/baselib-builtins.pyj +340 -2
- package/src/baselib-bytes.pyj +664 -0
- package/src/baselib-errors.pyj +1 -1
- package/src/baselib-internal.pyj +267 -60
- package/src/baselib-itertools.pyj +110 -97
- package/src/baselib-str.pyj +22 -4
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/abc.pyj +317 -0
- package/src/lib/aes.pyj +646 -646
- package/src/lib/contextlib.pyj +379 -0
- package/src/lib/copy.pyj +120 -120
- package/src/lib/dataclasses.pyj +532 -0
- package/src/lib/datetime.pyj +712 -0
- package/src/lib/elementmaker.pyj +83 -83
- package/src/lib/encodings.pyj +126 -126
- package/src/lib/enum.pyj +125 -0
- package/src/lib/gettext.pyj +569 -569
- package/src/lib/io.pyj +500 -0
- package/src/lib/itertools.pyj +580 -580
- package/src/lib/json.pyj +227 -0
- package/src/lib/math.pyj +193 -193
- package/src/lib/operator.pyj +11 -11
- package/src/lib/pythonize.pyj +20 -20
- package/src/lib/random.pyj +118 -118
- package/src/lib/re.pyj +504 -470
- package/src/lib/react.pyj +74 -74
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/typing.pyj +577 -0
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/builtins.js +14 -4
- package/src/monaco-language-service/diagnostics.js +19 -20
- package/src/monaco-language-service/dts.js +550 -550
- package/src/output/classes.pyj +62 -26
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -201
- package/src/output/functions.pyj +78 -5
- package/src/output/jsx.pyj +164 -164
- package/src/output/loops.pyj +5 -2
- package/src/output/operators.pyj +100 -34
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +80 -16
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +10 -5
- package/src/unicode_aliases.pyj +576 -576
- package/src/utils.pyj +192 -192
- package/test/_import_one.pyj +37 -37
- package/test/_import_two/__init__.pyj +11 -11
- package/test/_import_two/level2/deep.pyj +4 -4
- package/test/_import_two/other.pyj +6 -6
- package/test/_import_two/sub.pyj +13 -13
- package/test/abc.pyj +291 -0
- package/test/aes_vectors.pyj +421 -421
- package/test/annotations.pyj +80 -80
- package/test/arithmetic_nostrict.pyj +88 -0
- package/test/arithmetic_types.pyj +169 -0
- package/test/baselib.pyj +91 -0
- package/test/bytes.pyj +467 -0
- package/test/classes.pyj +1 -0
- package/test/comparison_ops.pyj +173 -0
- package/test/contextlib.pyj +362 -0
- package/test/dataclasses.pyj +253 -0
- package/test/datetime.pyj +500 -0
- package/test/debugger_stmt.pyj +41 -0
- package/test/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- package/test/enum.pyj +134 -0
- package/test/eval_exec.pyj +56 -0
- package/test/format.pyj +148 -0
- package/test/functions.pyj +151 -151
- package/test/generators.pyj +41 -41
- package/test/generic.pyj +370 -370
- package/test/imports.pyj +72 -72
- package/test/internationalization.pyj +73 -73
- package/test/io.pyj +316 -0
- package/test/json.pyj +196 -0
- package/test/lint.pyj +164 -164
- package/test/loops.pyj +85 -85
- package/test/numpy.pyj +734 -734
- package/test/object.pyj +64 -0
- package/test/omit_function_metadata.pyj +20 -20
- package/test/python_compat.pyj +17 -15
- package/test/python_features.pyj +70 -15
- package/test/regexp.pyj +83 -55
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/tuples.pyj +96 -0
- package/test/typing.pyj +469 -0
- package/test/unit/index.js +116 -7
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service.js +84 -0
- package/test/unit/web-repl.js +1337 -1
- package/test/vars_locals_globals.pyj +94 -0
- package/tools/cli.js +558 -547
- package/tools/compile.js +224 -219
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +262 -251
- package/tools/gettext.js +185 -185
- package/tools/ini.js +65 -65
- package/tools/lint.js +16 -19
- package/tools/msgfmt.js +187 -187
- package/tools/repl.js +223 -223
- package/tools/test.js +118 -118
- package/tools/utils.js +128 -128
- package/tools/web_repl.js +95 -95
- package/try +41 -41
- package/web-repl/env.js +196 -196
- package/web-repl/index.html +163 -163
- package/web-repl/main.js +252 -252
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +224 -224
- package/web-repl/sha1.js +25 -25
- package/PYTHON_DIFFERENCES_REPORT.md +0 -291
- package/PYTHON_FEATURE_COVERAGE.md +0 -200
package/src/output/classes.pyj
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
3
|
from __python__ import hash_literals
|
|
4
4
|
|
|
5
|
-
from ast import AST_Class, AST_Method, is_node_type
|
|
5
|
+
from ast import AST_Class, AST_Method, AST_AnnotatedAssign, AST_SymbolRef, is_node_type
|
|
6
6
|
from output.functions import decorate, function_definition, function_annotation
|
|
7
7
|
from output.utils import create_doctring
|
|
8
8
|
from utils import has_prop
|
|
@@ -291,6 +291,17 @@ def print_class(output):
|
|
|
291
291
|
output.end_statement()
|
|
292
292
|
)
|
|
293
293
|
|
|
294
|
+
if not defined_methods['__format__']:
|
|
295
|
+
define_default_method('__format__', def():
|
|
296
|
+
if self.parent:
|
|
297
|
+
output.print('if('), self.parent.print(output), output.spaced('.prototype.__format__)', 'return', self.parent)
|
|
298
|
+
output.print('.prototype.__format__.call(this, arguments[0])'), output.end_statement()
|
|
299
|
+
output.indent(), output.spaced('if', '(!arguments[0])', 'return', 'this.__str__()')
|
|
300
|
+
output.end_statement()
|
|
301
|
+
output.indent(), output.spaced('throw', 'new TypeError("unsupported format specification")')
|
|
302
|
+
output.end_statement()
|
|
303
|
+
)
|
|
304
|
+
|
|
294
305
|
# Python semantics: defining __eq__ without __hash__ makes the class unhashable
|
|
295
306
|
if defined_methods['__eq__'] and not defined_methods['__hash__']:
|
|
296
307
|
output.indent()
|
|
@@ -319,7 +330,56 @@ def print_class(output):
|
|
|
319
330
|
output.print('.prototype, "__class__", {get: function() { return this.constructor; }, configurable: true})')
|
|
320
331
|
output.end_statement()
|
|
321
332
|
|
|
322
|
-
#
|
|
333
|
+
# Other statements in the class context (including nested class definitions).
|
|
334
|
+
# Emitted BEFORE __init_subclass__ so that the hook can see class variables.
|
|
335
|
+
# This matches Python's behaviour: the class body executes first, then the
|
|
336
|
+
# hook is called with the fully-populated class namespace.
|
|
337
|
+
for stmt in self.statements:
|
|
338
|
+
if is_node_type(stmt, AST_Class):
|
|
339
|
+
# Print the nested class in full, then attach it to the outer class.
|
|
340
|
+
# Two assignments mirror Python semantics:
|
|
341
|
+
# Outer.Inner — class-level access (Outer.Inner())
|
|
342
|
+
# Outer.prototype.Inner — instance-level access (self.Inner() inside methods)
|
|
343
|
+
output.indent()
|
|
344
|
+
stmt.print(output)
|
|
345
|
+
output.newline()
|
|
346
|
+
nested_name = stmt.name.name
|
|
347
|
+
output.indent()
|
|
348
|
+
self.name.print(output)
|
|
349
|
+
output.print('.' + nested_name + ' = ' + nested_name)
|
|
350
|
+
output.end_statement()
|
|
351
|
+
output.indent()
|
|
352
|
+
self.name.print(output)
|
|
353
|
+
output.print('.prototype.' + nested_name + ' = ' + nested_name)
|
|
354
|
+
output.end_statement()
|
|
355
|
+
elif not is_node_type(stmt, AST_Method):
|
|
356
|
+
output.indent()
|
|
357
|
+
stmt.print(output)
|
|
358
|
+
output.newline()
|
|
359
|
+
|
|
360
|
+
# Emit __annotations__ for annotated class variables so that @dataclass and
|
|
361
|
+
# similar decorators can introspect field names and their declaration order.
|
|
362
|
+
# Only annotation-with-value statements (x: T = v) AND annotation-only
|
|
363
|
+
# statements (x: T) are collected; the value (if any) is already emitted
|
|
364
|
+
# above as a prototype assignment. We store null as the type since type
|
|
365
|
+
# information is erased in the JS output.
|
|
366
|
+
annotated_field_names = []
|
|
367
|
+
for stmt in self.statements:
|
|
368
|
+
if is_node_type(stmt, AST_AnnotatedAssign) and is_node_type(stmt.target, AST_SymbolRef):
|
|
369
|
+
annotated_field_names.push(stmt.target.name)
|
|
370
|
+
if annotated_field_names.length:
|
|
371
|
+
output.indent()
|
|
372
|
+
self.name.print(output)
|
|
373
|
+
output.print('.__annotations__ = {')
|
|
374
|
+
for i in range(annotated_field_names.length):
|
|
375
|
+
if i > 0:
|
|
376
|
+
output.comma()
|
|
377
|
+
output.print(JSON.stringify(annotated_field_names[i]) + ': null')
|
|
378
|
+
output.print('}')
|
|
379
|
+
output.end_statement()
|
|
380
|
+
|
|
381
|
+
# __init_subclass__ hook: call after identity properties and class variables
|
|
382
|
+
# so cls.__name__ is correct and cls.prototype reflects the full class body.
|
|
323
383
|
if self.parent:
|
|
324
384
|
output.indent()
|
|
325
385
|
output.print('if (typeof ')
|
|
@@ -371,30 +431,6 @@ def print_class(output):
|
|
|
371
431
|
output.print(JSON.stringify(create_doctring(self.docstrings)))
|
|
372
432
|
)
|
|
373
433
|
|
|
374
|
-
# Other statements in the class context (including nested class definitions)
|
|
375
|
-
for stmt in self.statements:
|
|
376
|
-
if is_node_type(stmt, AST_Class):
|
|
377
|
-
# Print the nested class in full, then attach it to the outer class.
|
|
378
|
-
# Two assignments mirror Python semantics:
|
|
379
|
-
# Outer.Inner — class-level access (Outer.Inner())
|
|
380
|
-
# Outer.prototype.Inner — instance-level access (self.Inner() inside methods)
|
|
381
|
-
output.indent()
|
|
382
|
-
stmt.print(output)
|
|
383
|
-
output.newline()
|
|
384
|
-
nested_name = stmt.name.name
|
|
385
|
-
output.indent()
|
|
386
|
-
self.name.print(output)
|
|
387
|
-
output.print('.' + nested_name + ' = ' + nested_name)
|
|
388
|
-
output.end_statement()
|
|
389
|
-
output.indent()
|
|
390
|
-
self.name.print(output)
|
|
391
|
-
output.print('.prototype.' + nested_name + ' = ' + nested_name)
|
|
392
|
-
output.end_statement()
|
|
393
|
-
elif not is_node_type(stmt, AST_Method):
|
|
394
|
-
output.indent()
|
|
395
|
-
stmt.print(output)
|
|
396
|
-
output.newline()
|
|
397
|
-
|
|
398
434
|
if decorators.length:
|
|
399
435
|
output.indent()
|
|
400
436
|
output.assign(self.name)
|
package/src/output/comments.pyj
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# vim:fileencoding=utf-8
|
|
2
|
-
# License: BSD Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
-
from __python__ import hash_literals
|
|
4
|
-
|
|
5
|
-
from ast import AST_Exit, is_node_type
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def output_comments(comments, output, nlb):
|
|
9
|
-
for comm in comments:
|
|
10
|
-
if comm.type is "comment1":
|
|
11
|
-
output.print("//" + comm.value + "\n")
|
|
12
|
-
output.indent()
|
|
13
|
-
elif comm.type is "comment2":
|
|
14
|
-
output.print("/*" + comm.value + "*/")
|
|
15
|
-
if nlb:
|
|
16
|
-
output.print("\n")
|
|
17
|
-
output.indent()
|
|
18
|
-
else:
|
|
19
|
-
output.space()
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def print_comments(self, output):
|
|
23
|
-
c = output.options.comments
|
|
24
|
-
if c:
|
|
25
|
-
start = self.start
|
|
26
|
-
if start and not start._comments_dumped:
|
|
27
|
-
start._comments_dumped = True
|
|
28
|
-
comments = start.comments_before
|
|
29
|
-
# XXX: ugly fix for https://github.com/mishoo/RapydScript2/issues/112
|
|
30
|
-
# if this node is `return` or `throw`, we cannot allow comments before
|
|
31
|
-
# the returned or thrown value.
|
|
32
|
-
if is_node_type(self, AST_Exit) and self.value and self.value.start.comments_before and self.value.start.comments_before.length > 0:
|
|
33
|
-
comments = (comments or v'[]').concat(self.value.start.comments_before)
|
|
34
|
-
self.value.start.comments_before = v'[]'
|
|
35
|
-
|
|
36
|
-
if c.test:
|
|
37
|
-
comments = comments.filter(def(comment):
|
|
38
|
-
return c.test(comment.value)
|
|
39
|
-
)
|
|
40
|
-
elif jstype(c) is "function":
|
|
41
|
-
comments = comments.filter(def(comment):
|
|
42
|
-
return c(self, comment)
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
output_comments(comments, output, start.nlb)
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
from __python__ import hash_literals
|
|
4
|
+
|
|
5
|
+
from ast import AST_Exit, is_node_type
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def output_comments(comments, output, nlb):
|
|
9
|
+
for comm in comments:
|
|
10
|
+
if comm.type is "comment1":
|
|
11
|
+
output.print("//" + comm.value + "\n")
|
|
12
|
+
output.indent()
|
|
13
|
+
elif comm.type is "comment2":
|
|
14
|
+
output.print("/*" + comm.value + "*/")
|
|
15
|
+
if nlb:
|
|
16
|
+
output.print("\n")
|
|
17
|
+
output.indent()
|
|
18
|
+
else:
|
|
19
|
+
output.space()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def print_comments(self, output):
|
|
23
|
+
c = output.options.comments
|
|
24
|
+
if c:
|
|
25
|
+
start = self.start
|
|
26
|
+
if start and not start._comments_dumped:
|
|
27
|
+
start._comments_dumped = True
|
|
28
|
+
comments = start.comments_before
|
|
29
|
+
# XXX: ugly fix for https://github.com/mishoo/RapydScript2/issues/112
|
|
30
|
+
# if this node is `return` or `throw`, we cannot allow comments before
|
|
31
|
+
# the returned or thrown value.
|
|
32
|
+
if is_node_type(self, AST_Exit) and self.value and self.value.start.comments_before and self.value.start.comments_before.length > 0:
|
|
33
|
+
comments = (comments or v'[]').concat(self.value.start.comments_before)
|
|
34
|
+
self.value.start.comments_before = v'[]'
|
|
35
|
+
|
|
36
|
+
if c.test:
|
|
37
|
+
comments = comments.filter(def(comment):
|
|
38
|
+
return c.test(comment.value)
|
|
39
|
+
)
|
|
40
|
+
elif jstype(c) is "function":
|
|
41
|
+
comments = comments.filter(def(comment):
|
|
42
|
+
return c(self, comment)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
output_comments(comments, output, start.nlb)
|
|
@@ -1,201 +1,201 @@
|
|
|
1
|
-
# vim:fileencoding=utf-8
|
|
2
|
-
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
-
from __python__ import hash_literals
|
|
4
|
-
|
|
5
|
-
from output.statements import print_bracketed, display_body
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def print_try(self, output):
|
|
9
|
-
else_var_name = None
|
|
10
|
-
def update_output_var(output):
|
|
11
|
-
output.indent(), output.assign(else_var_name), output.print('true'), output.end_statement()
|
|
12
|
-
if self.belse:
|
|
13
|
-
else_var_name = output.new_try_else_counter()
|
|
14
|
-
output.assign('var ' + else_var_name), output.print('false'), output.end_statement(), output.indent()
|
|
15
|
-
output.print("try")
|
|
16
|
-
output.space()
|
|
17
|
-
print_bracketed(self, output, False, None, None, update_output_var if else_var_name else None)
|
|
18
|
-
if self.bcatch:
|
|
19
|
-
output.space()
|
|
20
|
-
print_catch(self.bcatch, output)
|
|
21
|
-
|
|
22
|
-
if self.bfinally:
|
|
23
|
-
output.space()
|
|
24
|
-
print_finally(self.bfinally, output, self.belse, else_var_name)
|
|
25
|
-
elif self.belse:
|
|
26
|
-
output.newline()
|
|
27
|
-
print_else(self.belse, else_var_name, output)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def print_catch(self, output):
|
|
31
|
-
# Dispatch to except* handler when any clause is an exception group handler
|
|
32
|
-
if self.body.length and self.body[0].is_star:
|
|
33
|
-
print_catch_star(self, output)
|
|
34
|
-
return
|
|
35
|
-
output.print("catch")
|
|
36
|
-
output.space()
|
|
37
|
-
output.with_parens(def():
|
|
38
|
-
output.print("ρσ_Exception")
|
|
39
|
-
)
|
|
40
|
-
output.space()
|
|
41
|
-
output.with_block(def():
|
|
42
|
-
output.indent()
|
|
43
|
-
output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
|
|
44
|
-
output.indent()
|
|
45
|
-
no_default = True
|
|
46
|
-
for i, exception in enumerate(self.body):
|
|
47
|
-
if i:
|
|
48
|
-
output.print("else ")
|
|
49
|
-
|
|
50
|
-
if exception.errors.length:
|
|
51
|
-
output.print("if")
|
|
52
|
-
output.space()
|
|
53
|
-
output.with_parens(def():
|
|
54
|
-
for i, err in enumerate(exception.errors):
|
|
55
|
-
if i:
|
|
56
|
-
output.newline()
|
|
57
|
-
output.indent()
|
|
58
|
-
output.print("||")
|
|
59
|
-
output.space()
|
|
60
|
-
|
|
61
|
-
output.print("ρσ_Exception")
|
|
62
|
-
output.space()
|
|
63
|
-
output.print("instanceof")
|
|
64
|
-
output.space()
|
|
65
|
-
if err.name is 'Exception':
|
|
66
|
-
output.print('Error')
|
|
67
|
-
else:
|
|
68
|
-
err.print(output)
|
|
69
|
-
)
|
|
70
|
-
output.space()
|
|
71
|
-
else:
|
|
72
|
-
no_default = False
|
|
73
|
-
print_bracketed(exception, output, True)
|
|
74
|
-
output.space()
|
|
75
|
-
if no_default:
|
|
76
|
-
output.print("else")
|
|
77
|
-
output.space()
|
|
78
|
-
output.with_block(def():
|
|
79
|
-
output.indent()
|
|
80
|
-
output.print("throw")
|
|
81
|
-
output.space()
|
|
82
|
-
output.print("ρσ_Exception")
|
|
83
|
-
output.semicolon()
|
|
84
|
-
output.newline()
|
|
85
|
-
)
|
|
86
|
-
output.newline()
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def _eg_type_cond(errors, varname):
|
|
91
|
-
# Build a JS condition string testing varname against each error type
|
|
92
|
-
parts = []
|
|
93
|
-
for err in errors:
|
|
94
|
-
if err.name is 'Exception':
|
|
95
|
-
parts.push(varname + " instanceof Error")
|
|
96
|
-
else:
|
|
97
|
-
parts.push(varname + " instanceof " + err.name)
|
|
98
|
-
return parts.join(" || ")
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def print_catch_star(self, output):
|
|
102
|
-
output.print("catch")
|
|
103
|
-
output.space()
|
|
104
|
-
output.with_parens(def():
|
|
105
|
-
output.print("ρσ_Exception")
|
|
106
|
-
)
|
|
107
|
-
output.space()
|
|
108
|
-
output.with_block(def():
|
|
109
|
-
output.indent()
|
|
110
|
-
output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
|
|
111
|
-
|
|
112
|
-
# Normalise: wrap non-ExceptionGroup exception into a one-element array
|
|
113
|
-
output.indent()
|
|
114
|
-
output.print("var ρσ_eg_exceptions = (ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.exceptions.slice() : [ρσ_Exception]")
|
|
115
|
-
output.semicolon(), output.newline()
|
|
116
|
-
output.indent()
|
|
117
|
-
output.print("var ρσ_eg_raised = []")
|
|
118
|
-
output.semicolon(), output.newline()
|
|
119
|
-
|
|
120
|
-
for ei, exception in enumerate(self.body):
|
|
121
|
-
idx = str(ei)
|
|
122
|
-
if exception.errors.length:
|
|
123
|
-
cond = _eg_type_cond(exception.errors, "ρσ_et")
|
|
124
|
-
output.indent()
|
|
125
|
-
output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.filter(function(ρσ_et) { return " + cond + "; })")
|
|
126
|
-
output.semicolon(), output.newline()
|
|
127
|
-
output.indent()
|
|
128
|
-
output.print("ρσ_eg_exceptions = ρσ_eg_exceptions.filter(function(ρσ_et) { return !(" + cond + "); })")
|
|
129
|
-
output.semicolon(), output.newline()
|
|
130
|
-
else:
|
|
131
|
-
# Bare except*: take all remaining
|
|
132
|
-
output.indent()
|
|
133
|
-
output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.slice()")
|
|
134
|
-
output.semicolon(), output.newline()
|
|
135
|
-
output.indent()
|
|
136
|
-
output.print("ρσ_eg_exceptions = []")
|
|
137
|
-
output.semicolon(), output.newline()
|
|
138
|
-
|
|
139
|
-
output.indent()
|
|
140
|
-
output.print("if (ρσ_eg_matched_" + idx + ".length > 0)")
|
|
141
|
-
output.space()
|
|
142
|
-
output.with_block(def():
|
|
143
|
-
if exception.argname:
|
|
144
|
-
output.indent()
|
|
145
|
-
output.print("var ")
|
|
146
|
-
output.assign(exception.argname)
|
|
147
|
-
output.print("(ρσ_Exception instanceof ExceptionGroup) ? new ExceptionGroup(ρσ_Exception.message, ρσ_eg_matched_" + idx + ") : ρσ_eg_matched_" + idx + "[0]")
|
|
148
|
-
output.semicolon(), output.newline()
|
|
149
|
-
output.indent()
|
|
150
|
-
output.print("try")
|
|
151
|
-
output.space()
|
|
152
|
-
output.with_block(def():
|
|
153
|
-
display_body(exception.body, False, output)
|
|
154
|
-
)
|
|
155
|
-
output.print(" catch (ρσ_eg_exc_" + idx + ")")
|
|
156
|
-
output.space()
|
|
157
|
-
output.with_block(def():
|
|
158
|
-
output.indent()
|
|
159
|
-
output.print("ρσ_eg_raised.push(ρσ_eg_exc_" + idx + ")")
|
|
160
|
-
output.semicolon(), output.newline()
|
|
161
|
-
)
|
|
162
|
-
output.newline()
|
|
163
|
-
)
|
|
164
|
-
output.newline()
|
|
165
|
-
|
|
166
|
-
# Re-raise unmatched exceptions and any raised by handlers
|
|
167
|
-
output.indent()
|
|
168
|
-
output.print("var ρσ_eg_unhandled = ρσ_eg_exceptions.concat(ρσ_eg_raised)")
|
|
169
|
-
output.semicolon(), output.newline()
|
|
170
|
-
output.indent()
|
|
171
|
-
output.print("if (ρσ_eg_unhandled.length > 0)")
|
|
172
|
-
output.space()
|
|
173
|
-
output.with_block(def():
|
|
174
|
-
output.indent()
|
|
175
|
-
output.print("throw (ρσ_eg_unhandled.length === 1 && !(ρσ_Exception instanceof ExceptionGroup)) ? ρσ_eg_unhandled[0] : new ExceptionGroup((ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.message : \"unhandled exceptions\", ρσ_eg_unhandled)")
|
|
176
|
-
output.semicolon(), output.newline()
|
|
177
|
-
)
|
|
178
|
-
output.newline()
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
def print_finally(self, output, belse, else_var_name):
|
|
183
|
-
output.print("finally")
|
|
184
|
-
output.space()
|
|
185
|
-
if else_var_name:
|
|
186
|
-
output.with_block(def():
|
|
187
|
-
output.indent(), output.print("try")
|
|
188
|
-
output.space()
|
|
189
|
-
output.with_block(def():
|
|
190
|
-
print_else(belse, else_var_name, output)
|
|
191
|
-
)
|
|
192
|
-
print_finally(self, output)
|
|
193
|
-
)
|
|
194
|
-
else:
|
|
195
|
-
print_bracketed(self, output)
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
def print_else(self, else_var_name, output):
|
|
199
|
-
output.indent(), output.spaced('if', '(' + else_var_name + ')')
|
|
200
|
-
output.space()
|
|
201
|
-
print_bracketed(self, output)
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
from __python__ import hash_literals
|
|
4
|
+
|
|
5
|
+
from output.statements import print_bracketed, display_body
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def print_try(self, output):
|
|
9
|
+
else_var_name = None
|
|
10
|
+
def update_output_var(output):
|
|
11
|
+
output.indent(), output.assign(else_var_name), output.print('true'), output.end_statement()
|
|
12
|
+
if self.belse:
|
|
13
|
+
else_var_name = output.new_try_else_counter()
|
|
14
|
+
output.assign('var ' + else_var_name), output.print('false'), output.end_statement(), output.indent()
|
|
15
|
+
output.print("try")
|
|
16
|
+
output.space()
|
|
17
|
+
print_bracketed(self, output, False, None, None, update_output_var if else_var_name else None)
|
|
18
|
+
if self.bcatch:
|
|
19
|
+
output.space()
|
|
20
|
+
print_catch(self.bcatch, output)
|
|
21
|
+
|
|
22
|
+
if self.bfinally:
|
|
23
|
+
output.space()
|
|
24
|
+
print_finally(self.bfinally, output, self.belse, else_var_name)
|
|
25
|
+
elif self.belse:
|
|
26
|
+
output.newline()
|
|
27
|
+
print_else(self.belse, else_var_name, output)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def print_catch(self, output):
|
|
31
|
+
# Dispatch to except* handler when any clause is an exception group handler
|
|
32
|
+
if self.body.length and self.body[0].is_star:
|
|
33
|
+
print_catch_star(self, output)
|
|
34
|
+
return
|
|
35
|
+
output.print("catch")
|
|
36
|
+
output.space()
|
|
37
|
+
output.with_parens(def():
|
|
38
|
+
output.print("ρσ_Exception")
|
|
39
|
+
)
|
|
40
|
+
output.space()
|
|
41
|
+
output.with_block(def():
|
|
42
|
+
output.indent()
|
|
43
|
+
output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
|
|
44
|
+
output.indent()
|
|
45
|
+
no_default = True
|
|
46
|
+
for i, exception in enumerate(self.body):
|
|
47
|
+
if i:
|
|
48
|
+
output.print("else ")
|
|
49
|
+
|
|
50
|
+
if exception.errors.length:
|
|
51
|
+
output.print("if")
|
|
52
|
+
output.space()
|
|
53
|
+
output.with_parens(def():
|
|
54
|
+
for i, err in enumerate(exception.errors):
|
|
55
|
+
if i:
|
|
56
|
+
output.newline()
|
|
57
|
+
output.indent()
|
|
58
|
+
output.print("||")
|
|
59
|
+
output.space()
|
|
60
|
+
|
|
61
|
+
output.print("ρσ_Exception")
|
|
62
|
+
output.space()
|
|
63
|
+
output.print("instanceof")
|
|
64
|
+
output.space()
|
|
65
|
+
if err.name is 'Exception':
|
|
66
|
+
output.print('Error')
|
|
67
|
+
else:
|
|
68
|
+
err.print(output)
|
|
69
|
+
)
|
|
70
|
+
output.space()
|
|
71
|
+
else:
|
|
72
|
+
no_default = False
|
|
73
|
+
print_bracketed(exception, output, True)
|
|
74
|
+
output.space()
|
|
75
|
+
if no_default:
|
|
76
|
+
output.print("else")
|
|
77
|
+
output.space()
|
|
78
|
+
output.with_block(def():
|
|
79
|
+
output.indent()
|
|
80
|
+
output.print("throw")
|
|
81
|
+
output.space()
|
|
82
|
+
output.print("ρσ_Exception")
|
|
83
|
+
output.semicolon()
|
|
84
|
+
output.newline()
|
|
85
|
+
)
|
|
86
|
+
output.newline()
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _eg_type_cond(errors, varname):
|
|
91
|
+
# Build a JS condition string testing varname against each error type
|
|
92
|
+
parts = []
|
|
93
|
+
for err in errors:
|
|
94
|
+
if err.name is 'Exception':
|
|
95
|
+
parts.push(varname + " instanceof Error")
|
|
96
|
+
else:
|
|
97
|
+
parts.push(varname + " instanceof " + err.name)
|
|
98
|
+
return parts.join(" || ")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def print_catch_star(self, output):
|
|
102
|
+
output.print("catch")
|
|
103
|
+
output.space()
|
|
104
|
+
output.with_parens(def():
|
|
105
|
+
output.print("ρσ_Exception")
|
|
106
|
+
)
|
|
107
|
+
output.space()
|
|
108
|
+
output.with_block(def():
|
|
109
|
+
output.indent()
|
|
110
|
+
output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
|
|
111
|
+
|
|
112
|
+
# Normalise: wrap non-ExceptionGroup exception into a one-element array
|
|
113
|
+
output.indent()
|
|
114
|
+
output.print("var ρσ_eg_exceptions = (ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.exceptions.slice() : [ρσ_Exception]")
|
|
115
|
+
output.semicolon(), output.newline()
|
|
116
|
+
output.indent()
|
|
117
|
+
output.print("var ρσ_eg_raised = []")
|
|
118
|
+
output.semicolon(), output.newline()
|
|
119
|
+
|
|
120
|
+
for ei, exception in enumerate(self.body):
|
|
121
|
+
idx = str(ei)
|
|
122
|
+
if exception.errors.length:
|
|
123
|
+
cond = _eg_type_cond(exception.errors, "ρσ_et")
|
|
124
|
+
output.indent()
|
|
125
|
+
output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.filter(function(ρσ_et) { return " + cond + "; })")
|
|
126
|
+
output.semicolon(), output.newline()
|
|
127
|
+
output.indent()
|
|
128
|
+
output.print("ρσ_eg_exceptions = ρσ_eg_exceptions.filter(function(ρσ_et) { return !(" + cond + "); })")
|
|
129
|
+
output.semicolon(), output.newline()
|
|
130
|
+
else:
|
|
131
|
+
# Bare except*: take all remaining
|
|
132
|
+
output.indent()
|
|
133
|
+
output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.slice()")
|
|
134
|
+
output.semicolon(), output.newline()
|
|
135
|
+
output.indent()
|
|
136
|
+
output.print("ρσ_eg_exceptions = []")
|
|
137
|
+
output.semicolon(), output.newline()
|
|
138
|
+
|
|
139
|
+
output.indent()
|
|
140
|
+
output.print("if (ρσ_eg_matched_" + idx + ".length > 0)")
|
|
141
|
+
output.space()
|
|
142
|
+
output.with_block(def():
|
|
143
|
+
if exception.argname:
|
|
144
|
+
output.indent()
|
|
145
|
+
output.print("var ")
|
|
146
|
+
output.assign(exception.argname)
|
|
147
|
+
output.print("(ρσ_Exception instanceof ExceptionGroup) ? new ExceptionGroup(ρσ_Exception.message, ρσ_eg_matched_" + idx + ") : ρσ_eg_matched_" + idx + "[0]")
|
|
148
|
+
output.semicolon(), output.newline()
|
|
149
|
+
output.indent()
|
|
150
|
+
output.print("try")
|
|
151
|
+
output.space()
|
|
152
|
+
output.with_block(def():
|
|
153
|
+
display_body(exception.body, False, output)
|
|
154
|
+
)
|
|
155
|
+
output.print(" catch (ρσ_eg_exc_" + idx + ")")
|
|
156
|
+
output.space()
|
|
157
|
+
output.with_block(def():
|
|
158
|
+
output.indent()
|
|
159
|
+
output.print("ρσ_eg_raised.push(ρσ_eg_exc_" + idx + ")")
|
|
160
|
+
output.semicolon(), output.newline()
|
|
161
|
+
)
|
|
162
|
+
output.newline()
|
|
163
|
+
)
|
|
164
|
+
output.newline()
|
|
165
|
+
|
|
166
|
+
# Re-raise unmatched exceptions and any raised by handlers
|
|
167
|
+
output.indent()
|
|
168
|
+
output.print("var ρσ_eg_unhandled = ρσ_eg_exceptions.concat(ρσ_eg_raised)")
|
|
169
|
+
output.semicolon(), output.newline()
|
|
170
|
+
output.indent()
|
|
171
|
+
output.print("if (ρσ_eg_unhandled.length > 0)")
|
|
172
|
+
output.space()
|
|
173
|
+
output.with_block(def():
|
|
174
|
+
output.indent()
|
|
175
|
+
output.print("throw (ρσ_eg_unhandled.length === 1 && !(ρσ_Exception instanceof ExceptionGroup)) ? ρσ_eg_unhandled[0] : new ExceptionGroup((ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.message : \"unhandled exceptions\", ρσ_eg_unhandled)")
|
|
176
|
+
output.semicolon(), output.newline()
|
|
177
|
+
)
|
|
178
|
+
output.newline()
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def print_finally(self, output, belse, else_var_name):
|
|
183
|
+
output.print("finally")
|
|
184
|
+
output.space()
|
|
185
|
+
if else_var_name:
|
|
186
|
+
output.with_block(def():
|
|
187
|
+
output.indent(), output.print("try")
|
|
188
|
+
output.space()
|
|
189
|
+
output.with_block(def():
|
|
190
|
+
print_else(belse, else_var_name, output)
|
|
191
|
+
)
|
|
192
|
+
print_finally(self, output)
|
|
193
|
+
)
|
|
194
|
+
else:
|
|
195
|
+
print_bracketed(self, output)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def print_else(self, else_var_name, output):
|
|
199
|
+
output.indent(), output.spaced('if', '(' + else_var_name + ')')
|
|
200
|
+
output.space()
|
|
201
|
+
print_bracketed(self, output)
|