rapydscript-ns 0.8.3 → 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/.agignore +1 -1
- package/.github/workflows/ci.yml +38 -38
- package/=template.pyj +5 -5
- package/CHANGELOG.md +8 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/PYTHON_DIFFERENCES_REPORT.md +2 -2
- package/PYTHON_FEATURE_COVERAGE.md +13 -13
- package/README.md +670 -6
- package/TODO.md +5 -6
- 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 +155 -6
- package/package.json +1 -1
- package/publish.py +37 -37
- package/release/baselib-plain-pretty.js +2006 -229
- package/release/baselib-plain-ugly.js +70 -3
- package/release/compiler.js +11554 -3870
- package/release/signatures.json +31 -29
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/ast.pyj +93 -1
- package/src/baselib-builtins.pyj +22 -1
- package/src/baselib-containers.pyj +99 -0
- package/src/baselib-errors.pyj +44 -0
- package/src/baselib-internal.pyj +94 -4
- package/src/baselib-itertools.pyj +97 -97
- package/src/baselib-str.pyj +24 -0
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- package/src/lib/copy.pyj +120 -0
- package/src/lib/elementmaker.pyj +83 -83
- package/src/lib/encodings.pyj +126 -126
- package/src/lib/gettext.pyj +569 -569
- package/src/lib/itertools.pyj +580 -580
- 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 +470 -470
- package/src/lib/react.pyj +74 -0
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/builtins.js +5 -0
- package/src/monaco-language-service/diagnostics.js +25 -3
- package/src/monaco-language-service/dts.js +550 -550
- package/src/output/classes.pyj +108 -8
- package/src/output/codegen.pyj +16 -2
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -105
- package/src/output/functions.pyj +9 -0
- package/src/output/jsx.pyj +164 -0
- package/src/output/literals.pyj +28 -2
- package/src/output/modules.pyj +1 -1
- package/src/output/operators.pyj +8 -2
- package/src/output/statements.pyj +2 -2
- package/src/output/stream.pyj +1 -0
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +417 -113
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +29 -0
- 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/aes_vectors.pyj +421 -421
- package/test/annotations.pyj +80 -80
- package/test/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- 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/lint.pyj +164 -164
- package/test/loops.pyj +85 -85
- package/test/numpy.pyj +734 -734
- package/test/omit_function_metadata.pyj +20 -20
- package/test/python_features.pyj +19 -6
- package/test/regexp.pyj +55 -55
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/unit/index.js +2177 -64
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service.js +590 -4
- package/test/unit/web-repl.js +303 -0
- package/tools/cli.js +547 -547
- package/tools/compile.js +219 -219
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +251 -251
- package/tools/gettext.js +185 -185
- package/tools/ini.js +65 -65
- 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 -74
- package/web-repl/index.html +163 -163
- package/web-repl/main.js +252 -254
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +224 -102
- package/web-repl/sha1.js +25 -25
- package/hack_demo.pyj +0 -112
package/src/output/classes.pyj
CHANGED
|
@@ -82,19 +82,75 @@ def print_class(output):
|
|
|
82
82
|
output.with_block(def():
|
|
83
83
|
output.indent()
|
|
84
84
|
cname = self.name.name
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
if self.has_new:
|
|
86
|
+
# When __new__ is defined, call it to get the instance
|
|
87
|
+
output.print('if (!(this instanceof ' + cname + '))')
|
|
88
|
+
output.space()
|
|
89
|
+
output.with_block(def():
|
|
90
|
+
output.indent()
|
|
91
|
+
output.print('var ρσ_instance = ')
|
|
92
|
+
self.name.print(output)
|
|
93
|
+
output.print('.__new__(')
|
|
94
|
+
self.name.print(output)
|
|
95
|
+
output.print(', ...arguments)')
|
|
96
|
+
output.end_statement()
|
|
97
|
+
output.indent()
|
|
98
|
+
output.print('if (ρσ_instance instanceof ')
|
|
99
|
+
self.name.print(output)
|
|
100
|
+
output.print(')')
|
|
101
|
+
output.space()
|
|
102
|
+
output.with_block(def():
|
|
103
|
+
output.indent()
|
|
104
|
+
output.spaced('if', '(ρσ_instance.ρσ_object_id', '===', 'undefined)', 'Object.defineProperty(ρσ_instance,', '"ρσ_object_id",', '{"value":++ρσ_object_counter})')
|
|
105
|
+
output.end_statement()
|
|
106
|
+
if self.bound.length:
|
|
107
|
+
output.indent()
|
|
108
|
+
self.name.print(output), output.print('.prototype.__bind_methods__ && ')
|
|
109
|
+
self.name.print(output), output.print('.prototype.__bind_methods__.call(ρσ_instance)')
|
|
110
|
+
output.end_statement()
|
|
111
|
+
output.indent()
|
|
112
|
+
self.name.print(output)
|
|
113
|
+
output.print('.prototype.__init__.apply(ρσ_instance'), output.comma(), output.print('arguments)')
|
|
114
|
+
output.end_statement()
|
|
115
|
+
)
|
|
116
|
+
output.newline()
|
|
117
|
+
output.indent()
|
|
118
|
+
output.print('return ρσ_instance')
|
|
119
|
+
output.end_statement()
|
|
120
|
+
)
|
|
121
|
+
output.newline()
|
|
122
|
+
else:
|
|
123
|
+
output.print('if (!(this instanceof ' + cname + ')) return new ' + cname + '(...arguments);')
|
|
124
|
+
output.newline()
|
|
87
125
|
output.indent()
|
|
88
126
|
output.spaced('if', '(this.ρσ_object_id', '===', 'undefined)', 'Object.defineProperty(this,', '"ρσ_object_id",', '{"value":++ρσ_object_counter})')
|
|
89
127
|
output.end_statement()
|
|
90
|
-
if self.
|
|
128
|
+
if self.has_attr_dunders:
|
|
129
|
+
# Wrap in a Proxy so __getattr__/__setattr__/__delattr__/__getattribute__ are triggered.
|
|
91
130
|
output.indent()
|
|
92
|
-
|
|
131
|
+
output.print('var ρσ_proxy = ρσ_JS_Proxy ? new ρσ_JS_Proxy(this, ρσ_attr_proxy_handler) : this')
|
|
132
|
+
output.end_statement()
|
|
133
|
+
if self.bound.length:
|
|
134
|
+
output.indent()
|
|
135
|
+
self.name.print(output), output.print(".prototype.__bind_methods__ && ")
|
|
136
|
+
self.name.print(output), output.print(".prototype.__bind_methods__.call(ρσ_proxy)")
|
|
137
|
+
output.end_statement()
|
|
138
|
+
output.indent()
|
|
139
|
+
self.name.print(output)
|
|
140
|
+
output.print(".prototype.__init__.apply(ρσ_proxy"), output.comma(), output.print('arguments)')
|
|
141
|
+
output.end_statement()
|
|
142
|
+
output.indent()
|
|
143
|
+
output.print('return ρσ_proxy')
|
|
144
|
+
output.end_statement()
|
|
145
|
+
else:
|
|
146
|
+
if self.bound.length:
|
|
147
|
+
output.indent()
|
|
148
|
+
self.name.print(output), output.print(".prototype.__bind_methods__.call(this)")
|
|
149
|
+
output.end_statement()
|
|
150
|
+
output.indent()
|
|
151
|
+
self.name.print(output)
|
|
152
|
+
output.print(".prototype.__init__.apply(this"), output.comma(), output.print('arguments)')
|
|
93
153
|
output.end_statement()
|
|
94
|
-
output.indent()
|
|
95
|
-
self.name.print(output)
|
|
96
|
-
output.print(".prototype.__init__.apply(this"), output.comma(), output.print('arguments)')
|
|
97
|
-
output.end_statement()
|
|
98
154
|
)
|
|
99
155
|
|
|
100
156
|
decorators = self.decorators or v'[]'
|
|
@@ -235,6 +291,13 @@ def print_class(output):
|
|
|
235
291
|
output.end_statement()
|
|
236
292
|
)
|
|
237
293
|
|
|
294
|
+
# Python semantics: defining __eq__ without __hash__ makes the class unhashable
|
|
295
|
+
if defined_methods['__eq__'] and not defined_methods['__hash__']:
|
|
296
|
+
output.indent()
|
|
297
|
+
self.name.print(output)
|
|
298
|
+
output.print('.prototype.__hash__ = null')
|
|
299
|
+
output.end_statement()
|
|
300
|
+
|
|
238
301
|
# Multiple inheritance
|
|
239
302
|
add_hidden_property('__bases__', def():
|
|
240
303
|
output.print('[')
|
|
@@ -256,6 +319,43 @@ def print_class(output):
|
|
|
256
319
|
output.print('.prototype, "__class__", {get: function() { return this.constructor; }, configurable: true})')
|
|
257
320
|
output.end_statement()
|
|
258
321
|
|
|
322
|
+
# __init_subclass__ hook: call after identity properties so cls.__name__ is correct
|
|
323
|
+
if self.parent:
|
|
324
|
+
output.indent()
|
|
325
|
+
output.print('if (typeof ')
|
|
326
|
+
self.parent.print(output)
|
|
327
|
+
output.print('.__init_subclass__ === "function")')
|
|
328
|
+
output.space()
|
|
329
|
+
kws = self.class_kwargs
|
|
330
|
+
if kws and kws.length:
|
|
331
|
+
output.with_block(def():
|
|
332
|
+
output.indent()
|
|
333
|
+
output.print('var ρσ_isc_kw = {')
|
|
334
|
+
for v'var ρσ_kwi = 0; ρσ_kwi < kws.length; ρσ_kwi++':
|
|
335
|
+
if ρσ_kwi > 0:
|
|
336
|
+
output.comma()
|
|
337
|
+
output.print(kws[ρσ_kwi][0].name + ':')
|
|
338
|
+
output.space()
|
|
339
|
+
kws[ρσ_kwi][1].print(output)
|
|
340
|
+
output.print('}')
|
|
341
|
+
output.end_statement()
|
|
342
|
+
output.indent()
|
|
343
|
+
output.print('ρσ_isc_kw[ρσ_kwargs_symbol] = true')
|
|
344
|
+
output.end_statement()
|
|
345
|
+
output.indent()
|
|
346
|
+
self.parent.print(output)
|
|
347
|
+
output.print('.__init_subclass__.call(')
|
|
348
|
+
self.name.print(output)
|
|
349
|
+
output.print(', ρσ_isc_kw)')
|
|
350
|
+
output.end_statement()
|
|
351
|
+
)
|
|
352
|
+
else:
|
|
353
|
+
self.parent.print(output)
|
|
354
|
+
output.print('.__init_subclass__.call(')
|
|
355
|
+
self.name.print(output)
|
|
356
|
+
output.print(')')
|
|
357
|
+
output.end_statement()
|
|
358
|
+
|
|
259
359
|
if self.bases.length > 1:
|
|
260
360
|
output.indent()
|
|
261
361
|
output.print("ρσ_mixin(")
|
package/src/output/codegen.pyj
CHANGED
|
@@ -13,13 +13,14 @@ from ast import (
|
|
|
13
13
|
AST_EmptyStatement, AST_Exit, AST_ExpressiveObject, AST_ForIn,
|
|
14
14
|
AST_ForJS, AST_Function, AST_Hole, AST_If, AST_Imports, AST_Infinity,
|
|
15
15
|
AST_Lambda, AST_ListComprehension, AST_LoopControl, AST_NaN, AST_NamedExpr, AST_New, AST_Node,
|
|
16
|
-
AST_Number, AST_Object, AST_ObjectKeyVal, AST_ObjectProperty, AST_ObjectSpread, AST_PropAccess,
|
|
16
|
+
AST_Number, AST_Object, AST_ObjectKeyVal, AST_ObjectProperty, AST_ObjectSpread, AST_Spread, AST_PropAccess,
|
|
17
17
|
AST_RegExp, AST_Return, AST_Set, AST_Seq, AST_SimpleStatement, AST_Splice,
|
|
18
18
|
AST_Statement, AST_StatementWithBody, AST_String, AST_Sub, AST_ItemAccess,
|
|
19
19
|
AST_Symbol, AST_This, AST_Throw, AST_Toplevel, AST_Try, AST_Unary,
|
|
20
20
|
AST_UnaryPrefix, AST_Undefined, AST_Var, AST_VarDef, AST_Assert,
|
|
21
21
|
AST_Verbatim, AST_While, AST_With, AST_Yield, AST_Await, TreeWalker, AST_Existential,
|
|
22
|
-
AST_Match, AST_AnnotatedAssign, AST_Super
|
|
22
|
+
AST_Match, AST_AnnotatedAssign, AST_Super,
|
|
23
|
+
AST_JSXElement, AST_JSXFragment, AST_JSXAttribute, AST_JSXSpread, AST_JSXText, AST_JSXExprContainer
|
|
23
24
|
)
|
|
24
25
|
from output.exceptions import print_try
|
|
25
26
|
from output.classes import print_class
|
|
@@ -34,6 +35,7 @@ from output.operators import (
|
|
|
34
35
|
)
|
|
35
36
|
from output.functions import print_function, print_function_call
|
|
36
37
|
from output.statements import print_bracketed, first_in_statement, force_statement, print_with, print_assert, print_match, print_annotated_assign
|
|
38
|
+
from output.jsx import print_jsx_element, print_jsx_fragment, print_jsx_attribute, print_jsx_spread, print_jsx_text, print_jsx_expr_container
|
|
37
39
|
from output.utils import make_block, make_num
|
|
38
40
|
|
|
39
41
|
# -----[ code generators ]-----
|
|
@@ -486,6 +488,10 @@ def generate_code():
|
|
|
486
488
|
output.print('**')
|
|
487
489
|
self.value.print(output)
|
|
488
490
|
)
|
|
491
|
+
DEFPRINT(AST_Spread, def(self, output):
|
|
492
|
+
output.print('...')
|
|
493
|
+
self.expression.print(output)
|
|
494
|
+
)
|
|
489
495
|
DEFPRINT(AST_Set, print_set)
|
|
490
496
|
|
|
491
497
|
AST_Symbol.prototype.definition = def():
|
|
@@ -525,3 +531,11 @@ def generate_code():
|
|
|
525
531
|
output.print(make_num(self.value))
|
|
526
532
|
)
|
|
527
533
|
DEFPRINT(AST_RegExp, print_regexp)
|
|
534
|
+
|
|
535
|
+
# -----[ JSX ]-----
|
|
536
|
+
DEFPRINT(AST_JSXElement, print_jsx_element)
|
|
537
|
+
DEFPRINT(AST_JSXFragment, print_jsx_fragment)
|
|
538
|
+
DEFPRINT(AST_JSXAttribute, print_jsx_attribute)
|
|
539
|
+
DEFPRINT(AST_JSXSpread, print_jsx_spread)
|
|
540
|
+
DEFPRINT(AST_JSXText, print_jsx_text)
|
|
541
|
+
DEFPRINT(AST_JSXExprContainer, print_jsx_expr_container)
|
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,105 +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
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
)
|
|
36
|
-
output.space()
|
|
37
|
-
output.
|
|
38
|
-
output.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
output.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
output
|
|
74
|
-
output.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
output.
|
|
80
|
-
output.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
output.
|
|
104
|
-
output.
|
|
105
|
-
|
|
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)
|
package/src/output/functions.pyj
CHANGED
|
@@ -150,6 +150,15 @@ def function_preamble(node, output, offset):
|
|
|
150
150
|
output.print('.pop()')
|
|
151
151
|
output.end_statement()
|
|
152
152
|
|
|
153
|
+
# Convert the plain JS kwargs object to a proper Python dict so that
|
|
154
|
+
# kw.items(), kw.keys(), etc. work in the function body.
|
|
155
|
+
# This must happen AFTER defaults/kwonly/starargs processing which rely on
|
|
156
|
+
# plain property access (kw.name) and ρσ_kwargs_symbol checks.
|
|
157
|
+
if a.kwargs:
|
|
158
|
+
output.indent()
|
|
159
|
+
output.spaced(kw, '=', 'ρσ_kwargs_to_dict(' + kw + ')')
|
|
160
|
+
output.end_statement()
|
|
161
|
+
|
|
153
162
|
def has_annotations(self):
|
|
154
163
|
if self.return_annotation:
|
|
155
164
|
return True
|