rapydscript-ns 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.
Files changed (141) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +39 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_DIFFERENCES_REPORT.md +291 -0
  8. package/PYTHON_FEATURE_COVERAGE.md +106 -15
  9. package/README.md +831 -52
  10. package/TODO.md +4 -286
  11. package/add-toc-to-readme +2 -2
  12. package/bin/export +75 -75
  13. package/bin/rapydscript +70 -70
  14. package/bin/web-repl-export +102 -102
  15. package/build +2 -2
  16. package/language-service/index.js +4623 -0
  17. package/language-service/language-service.d.ts +40 -0
  18. package/package.json +9 -7
  19. package/publish.py +37 -37
  20. package/release/baselib-plain-pretty.js +2006 -229
  21. package/release/baselib-plain-ugly.js +70 -3
  22. package/release/compiler.js +11554 -3870
  23. package/release/signatures.json +31 -29
  24. package/session.vim +4 -4
  25. package/setup.cfg +2 -2
  26. package/src/ast.pyj +93 -1
  27. package/src/baselib-builtins.pyj +99 -2
  28. package/src/baselib-containers.pyj +107 -4
  29. package/src/baselib-errors.pyj +44 -0
  30. package/src/baselib-internal.pyj +124 -5
  31. package/src/baselib-itertools.pyj +97 -97
  32. package/src/baselib-str.pyj +32 -1
  33. package/src/compiler.pyj +36 -36
  34. package/src/errors.pyj +30 -30
  35. package/src/lib/aes.pyj +646 -646
  36. package/src/lib/collections.pyj +1 -1
  37. package/src/lib/copy.pyj +120 -0
  38. package/src/lib/elementmaker.pyj +83 -83
  39. package/src/lib/encodings.pyj +126 -126
  40. package/src/lib/gettext.pyj +569 -569
  41. package/src/lib/itertools.pyj +580 -580
  42. package/src/lib/math.pyj +193 -193
  43. package/src/lib/numpy.pyj +10 -10
  44. package/src/lib/operator.pyj +11 -11
  45. package/src/lib/pythonize.pyj +20 -20
  46. package/src/lib/random.pyj +118 -118
  47. package/src/lib/re.pyj +470 -470
  48. package/src/lib/react.pyj +74 -0
  49. package/src/lib/traceback.pyj +63 -63
  50. package/src/lib/uuid.pyj +77 -77
  51. package/src/monaco-language-service/analyzer.js +131 -9
  52. package/src/monaco-language-service/builtins.js +17 -2
  53. package/src/monaco-language-service/completions.js +170 -1
  54. package/src/monaco-language-service/diagnostics.js +25 -3
  55. package/src/monaco-language-service/dts.js +550 -550
  56. package/src/monaco-language-service/index.js +17 -0
  57. package/src/monaco-language-service/scope.js +3 -0
  58. package/src/output/classes.pyj +128 -11
  59. package/src/output/codegen.pyj +17 -3
  60. package/src/output/comments.pyj +45 -45
  61. package/src/output/exceptions.pyj +201 -105
  62. package/src/output/functions.pyj +13 -16
  63. package/src/output/jsx.pyj +164 -0
  64. package/src/output/literals.pyj +28 -2
  65. package/src/output/loops.pyj +0 -9
  66. package/src/output/modules.pyj +2 -5
  67. package/src/output/operators.pyj +22 -2
  68. package/src/output/statements.pyj +2 -2
  69. package/src/output/stream.pyj +1 -13
  70. package/src/output/treeshake.pyj +182 -182
  71. package/src/output/utils.pyj +72 -72
  72. package/src/parse.pyj +434 -114
  73. package/src/string_interpolation.pyj +72 -72
  74. package/src/tokenizer.pyj +29 -0
  75. package/src/unicode_aliases.pyj +576 -576
  76. package/src/utils.pyj +192 -192
  77. package/test/_import_one.pyj +37 -37
  78. package/test/_import_two/__init__.pyj +11 -11
  79. package/test/_import_two/level2/deep.pyj +4 -4
  80. package/test/_import_two/other.pyj +6 -6
  81. package/test/_import_two/sub.pyj +13 -13
  82. package/test/aes_vectors.pyj +421 -421
  83. package/test/annotations.pyj +80 -80
  84. package/test/baselib.pyj +4 -4
  85. package/test/classes.pyj +56 -17
  86. package/test/collections.pyj +5 -5
  87. package/test/decorators.pyj +77 -77
  88. package/test/docstrings.pyj +39 -39
  89. package/test/elementmaker_test.pyj +45 -45
  90. package/test/functions.pyj +151 -151
  91. package/test/generators.pyj +41 -41
  92. package/test/generic.pyj +370 -370
  93. package/test/imports.pyj +72 -72
  94. package/test/internationalization.pyj +73 -73
  95. package/test/lint.pyj +164 -164
  96. package/test/loops.pyj +85 -85
  97. package/test/numpy.pyj +734 -734
  98. package/test/omit_function_metadata.pyj +20 -20
  99. package/test/python_compat.pyj +326 -0
  100. package/test/python_features.pyj +129 -29
  101. package/test/regexp.pyj +55 -55
  102. package/test/repl.pyj +121 -121
  103. package/test/scoped_flags.pyj +76 -76
  104. package/test/slice.pyj +105 -0
  105. package/test/str.pyj +25 -0
  106. package/test/unit/fixtures/fibonacci_expected.js +1 -1
  107. package/test/unit/index.js +2296 -71
  108. package/test/unit/language-service-builtins.js +70 -0
  109. package/test/unit/language-service-bundle.js +5 -5
  110. package/test/unit/language-service-completions.js +180 -0
  111. package/test/unit/language-service-dts.js +543 -543
  112. package/test/unit/language-service-hover.js +455 -455
  113. package/test/unit/language-service-index.js +350 -0
  114. package/test/unit/language-service-scope.js +255 -0
  115. package/test/unit/language-service.js +625 -4
  116. package/test/unit/run-language-service.js +1 -0
  117. package/test/unit/web-repl.js +437 -0
  118. package/tools/build-language-service.js +2 -2
  119. package/tools/cli.js +547 -547
  120. package/tools/compile.js +219 -219
  121. package/tools/compiler.js +0 -24
  122. package/tools/completer.js +131 -131
  123. package/tools/embedded_compiler.js +251 -251
  124. package/tools/export.js +3 -37
  125. package/tools/gettext.js +185 -185
  126. package/tools/ini.js +65 -65
  127. package/tools/msgfmt.js +187 -187
  128. package/tools/repl.js +223 -223
  129. package/tools/test.js +118 -118
  130. package/tools/utils.js +128 -128
  131. package/tools/web_repl.js +95 -95
  132. package/try +41 -41
  133. package/web-repl/env.js +196 -74
  134. package/web-repl/index.html +163 -163
  135. package/web-repl/main.js +252 -254
  136. package/web-repl/prism.css +139 -139
  137. package/web-repl/prism.js +113 -113
  138. package/web-repl/rapydscript.js +227 -139
  139. package/web-repl/sha1.js +25 -25
  140. package/hack_demo.pyj +0 -112
  141. package/web-repl/language-service.js +0 -4187
@@ -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
- output.print("catch")
32
- output.space()
33
- output.with_parens(def():
34
- output.print("ρσ_Exception")
35
- )
36
- output.space()
37
- output.with_block(def():
38
- output.indent()
39
- output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
40
- output.indent()
41
- no_default = True
42
- for i, exception in enumerate(self.body):
43
- if i:
44
- output.print("else ")
45
-
46
- if exception.errors.length:
47
- output.print("if")
48
- output.space()
49
- output.with_parens(def():
50
- for i, err in enumerate(exception.errors):
51
- if i:
52
- output.newline()
53
- output.indent()
54
- output.print("||")
55
- output.space()
56
-
57
- output.print("ρσ_Exception")
58
- output.space()
59
- output.print("instanceof")
60
- output.space()
61
- if err.name is 'Exception':
62
- output.print('Error')
63
- else:
64
- err.print(output)
65
- )
66
- output.space()
67
- else:
68
- no_default = False
69
- print_bracketed(exception, output, True)
70
- output.space()
71
- if no_default:
72
- output.print("else")
73
- output.space()
74
- output.with_block(def():
75
- output.indent()
76
- output.print("throw")
77
- output.space()
78
- output.print("ρσ_Exception")
79
- output.semicolon()
80
- output.newline()
81
- )
82
- output.newline()
83
- )
84
-
85
-
86
- def print_finally(self, output, belse, else_var_name):
87
- output.print("finally")
88
- output.space()
89
- if else_var_name:
90
- output.with_block(def():
91
- output.indent(), output.print("try")
92
- output.space()
93
- output.with_block(def():
94
- print_else(belse, else_var_name, output)
95
- )
96
- print_finally(self, output)
97
- )
98
- else:
99
- print_bracketed(self, output)
100
-
101
-
102
- def print_else(self, else_var_name, output):
103
- output.indent(), output.spaced('if', '(' + else_var_name + ')')
104
- output.space()
105
- 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)
@@ -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_ClassCall, AST_New, has_calls, AST_Dot, AST_SymbolRef, is_node_type
@@ -151,6 +150,15 @@ def function_preamble(node, output, offset):
151
150
  output.print('.pop()')
152
151
  output.end_statement()
153
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
+
154
162
  def has_annotations(self):
155
163
  if self.return_annotation:
156
164
  return True
@@ -263,21 +271,10 @@ def function_definition(self, output, strip_first, as_expression):
263
271
  if self.is_generator:
264
272
  output.print('()'), output.space()
265
273
  output.with_block(def():
266
- if output.options.js_version >= 6:
267
- output.indent()
268
- output.print('function* js_generator')
269
- function_args(self.argnames, output, strip_first)
270
- print_bracketed(self, output, True, function_preamble)
271
- else:
272
- temp = OutputStream({'beautify':True})
273
- temp.print('function* js_generator')
274
- function_args(self.argnames, temp, strip_first)
275
- print_bracketed(self, temp, True, function_preamble)
276
- transpiled = regenerate(temp.get(), output.options.beautify).replace(/regeneratorRuntime.(wrap|mark)/g, 'ρσ_regenerator.regeneratorRuntime.$1')
277
- if output.options.beautify:
278
- ci = output.make_indent(0)
279
- transpiled = [ci + x for x in transpiled.split('\n')].join('\n')
280
- output.print(transpiled)
274
+ output.indent()
275
+ output.print('function* js_generator')
276
+ function_args(self.argnames, output, strip_first)
277
+ print_bracketed(self, output, True, function_preamble)
281
278
  output.newline()
282
279
  output.indent()
283
280
  output.spaced('var', 'result', '=', 'js_generator.apply(this,', 'arguments)')
@@ -0,0 +1,164 @@
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 ast import AST_String, AST_JSXText, AST_JSXSpread, AST_JSXExprContainer, is_node_type
6
+
7
+ def _is_component_tag(tag):
8
+ # Components start with uppercase or use dot notation (e.g. Router.Route)
9
+ first = tag[0]
10
+ return (first >= 'A' and first <= 'Z') or '.' in tag
11
+
12
+ def _needs_quoting(name):
13
+ # Attribute names containing non-identifier chars (e.g. aria-label) need quoting
14
+ return not v'/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)'
15
+
16
+ def _decode_html_entities(text):
17
+ # Decode HTML entities in a single pass to avoid double-decoding (e.g. &amp;lt; -> &lt;)
18
+ return text.replace(/&(?:#x([0-9a-fA-F]+)|#(\d+)|([a-zA-Z]+));/g, def(match, hex, dec, name):
19
+ if hex:
20
+ return String.fromCharCode(parseInt(hex, 16))
21
+ if dec:
22
+ return String.fromCharCode(parseInt(dec, 10))
23
+ if name is 'amp':
24
+ return '&'
25
+ if name is 'lt':
26
+ return '<'
27
+ if name is 'gt':
28
+ return '>'
29
+ if name is 'quot':
30
+ return '"'
31
+ if name is 'apos':
32
+ return "'"
33
+ if name is 'nbsp':
34
+ return '\u00a0'
35
+ return match
36
+ )
37
+
38
+ def _normalize_jsx_whitespace(text):
39
+ # Implements the Babel JSX whitespace algorithm:
40
+ # - Split by newlines; trim leading whitespace from all lines except the first,
41
+ # trailing whitespace from all lines except the last.
42
+ # - Lines that are empty after trimming are dropped.
43
+ # - Remaining non-empty lines are joined; each line except the last non-empty
44
+ # gets a trailing space to separate it from the next.
45
+ lines = text.split('\n')
46
+ last_non_empty = -1
47
+ for i in range(lines.length):
48
+ if /[^ \t]/.test(lines[i]):
49
+ last_non_empty = i
50
+ result = ''
51
+ for i in range(lines.length):
52
+ line = lines[i].replace(/\t/g, ' ')
53
+ is_first = (i is 0)
54
+ is_last = (i is lines.length - 1)
55
+ if not is_first:
56
+ line = line.replace(/^[ ]+/, '')
57
+ if not is_last:
58
+ line = line.replace(/[ ]+$/, '')
59
+ if line:
60
+ if i is not last_non_empty:
61
+ line += ' '
62
+ result += line
63
+ return result
64
+
65
+ def _process_jsx_text(text):
66
+ text = _normalize_jsx_whitespace(text)
67
+ if text:
68
+ text = _decode_html_entities(text)
69
+ return text
70
+
71
+ def _print_tag(tag, output):
72
+ if _is_component_tag(tag):
73
+ output.print(tag)
74
+ else:
75
+ output.print('"')
76
+ output.print(tag)
77
+ output.print('"')
78
+
79
+ def _print_props(props, output):
80
+ if not props or not props.length:
81
+ output.print('null')
82
+ return
83
+ output.print('{')
84
+ first = True
85
+ for prop in props:
86
+ if not first:
87
+ output.print(', ')
88
+ first = False
89
+ if is_node_type(prop, AST_JSXSpread):
90
+ output.print('...')
91
+ prop.expression.print(output)
92
+ else:
93
+ if _needs_quoting(prop.name):
94
+ output.print('"')
95
+ output.print(prop.name)
96
+ output.print('"')
97
+ else:
98
+ output.print(prop.name)
99
+ output.print(': ')
100
+ if prop.value is None:
101
+ output.print('true')
102
+ elif is_node_type(prop.value, AST_String):
103
+ output.print_string(prop.value.value)
104
+ else:
105
+ prop.value.print(output)
106
+ output.print('}')
107
+
108
+ def _print_children(children, output):
109
+ for child in children:
110
+ if is_node_type(child, AST_JSXText):
111
+ text = _process_jsx_text(child.value)
112
+ if text:
113
+ output.print(', ')
114
+ output.print_string(text)
115
+ elif is_node_type(child, AST_JSXExprContainer):
116
+ output.print(', ')
117
+ child.expression.print(output)
118
+ else:
119
+ output.print(', ')
120
+ child.print(output)
121
+
122
+ def print_jsx_element(self, output):
123
+ output.print('React.createElement(')
124
+ _print_tag(self.tag, output)
125
+ output.print(', ')
126
+ _print_props(self.props, output)
127
+ if not self.self_closing:
128
+ _print_children(self.children, output)
129
+ output.print(')')
130
+
131
+ def print_jsx_fragment(self, output):
132
+ output.print('React.createElement(React.Fragment, null')
133
+ _print_children(self.children, output)
134
+ output.print(')')
135
+
136
+ def print_jsx_attribute(self, output):
137
+ # Handled directly by _print_props; kept for completeness
138
+ if _needs_quoting(self.name):
139
+ output.print('"')
140
+ output.print(self.name)
141
+ output.print('"')
142
+ else:
143
+ output.print(self.name)
144
+ if self.value is not None:
145
+ output.print(': ')
146
+ if is_node_type(self.value, AST_String):
147
+ output.print_string(self.value.value)
148
+ else:
149
+ self.value.print(output)
150
+
151
+ def print_jsx_spread(self, output):
152
+ # Handled directly by _print_props; kept for completeness
153
+ output.print('...')
154
+ self.expression.print(output)
155
+
156
+ def print_jsx_text(self, output):
157
+ # Handled directly by _print_children; kept for completeness
158
+ text = _process_jsx_text(self.value)
159
+ if text:
160
+ output.print_string(text)
161
+
162
+ def print_jsx_expr_container(self, output):
163
+ # Handled directly by _print_children; kept for completeness
164
+ self.expression.print(output)
@@ -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_Binary, AST_ObjectSpread, is_node_type
5
+ from ast import AST_Binary, AST_ObjectSpread, AST_Spread, AST_SetItem, is_node_type
6
6
 
7
7
  def print_array(self, output):
8
8
  output.print('ρσ_list_decorate')
@@ -15,7 +15,11 @@ def print_array(self, output):
15
15
  for i, exp in enumerate(a):
16
16
  if i:
17
17
  output.comma()
18
- exp.print(output)
18
+ if is_node_type(exp, AST_Spread):
19
+ output.print('...')
20
+ exp.expression.print(output)
21
+ else:
22
+ exp.print(output)
19
23
  if len_ > 0:
20
24
  output.space()
21
25
  )
@@ -78,6 +82,28 @@ def print_object(self, output):
78
82
  output.print("Object.create(null)" if self.is_jshash else '{}')
79
83
 
80
84
  def print_set(self, output):
85
+ # Check for spread items: {*a, 1, 2, *b}
86
+ has_spread = False
87
+ for item in self.items:
88
+ if is_node_type(item, AST_Spread):
89
+ has_spread = True
90
+ break
91
+ if has_spread:
92
+ # Compile as ρσ_set([...a, 1, 2, ...b])
93
+ output.print('ρσ_set')
94
+ output.with_parens(def():
95
+ output.with_square(def():
96
+ for i, item in enumerate(self.items):
97
+ if i:
98
+ output.comma()
99
+ if is_node_type(item, AST_Spread):
100
+ output.print('...')
101
+ item.expression.print(output)
102
+ else:
103
+ item.value.print(output)
104
+ )
105
+ )
106
+ return
81
107
  if self.items.length is 0:
82
108
  output.print('ρσ_set()')
83
109
  return
@@ -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, AST_Starred, is_node_type
@@ -436,8 +435,6 @@ def print_list_comprehension(self, output):
436
435
  output.with_block(def():
437
436
  body_out = output
438
437
  if is_generator:
439
- if es5:
440
- body_out = OutputStream({'beautify':True})
441
438
  body_out.indent()
442
439
  body_out.print('function* js_generator()'), body_out.space(), body_out.print('{')
443
440
  body_out.newline()
@@ -485,12 +482,6 @@ def print_list_comprehension(self, output):
485
482
  if is_generator:
486
483
  output.set_indentation(previous_indentation)
487
484
  body_out.newline(), body_out.indent(), body_out.print('}') # end js_generator
488
- if es5:
489
- transpiled = regenerate(body_out.get(), output.options.beautify).replace(/regeneratorRuntime.(wrap|mark)/g, 'ρσ_regenerator.regeneratorRuntime.$1')
490
- if output.options.beautify:
491
- ci = output.make_indent(0)
492
- transpiled = [ci + x for x in transpiled.split('\n')].join('\n')
493
- output.print(transpiled)
494
485
  output.newline(), output.indent()
495
486
  output.spaced('var', 'result', '=', 'js_generator.call(this)')
496
487
  output.end_statement()
@@ -18,7 +18,7 @@ def write_imports(module, output):
18
18
  imports = []
19
19
  for import_id in Object.keys(module.imports):
20
20
  imports.push(module.imports[import_id])
21
- imports.sort(def(a, b):
21
+ imports.jssort(def(a, b):
22
22
  a, b = a.import_order, b.import_order
23
23
  return -1 if a < b else (1 if a > b else 0)
24
24
  )
@@ -122,9 +122,6 @@ def prologue(module, output):
122
122
  output.indent(), output.spaced('if(', 'typeof', 'HTMLCollection', '!==', '"undefined"', '&&', 'typeof', 'Symbol', '===', '"function")',
123
123
  'NodeList.prototype[Symbol.iterator]', '=', 'HTMLCollection.prototype[Symbol.iterator]', '=', 'NamedNodeMap.prototype[Symbol.iterator]', '=', 'Array.prototype[Symbol.iterator]')
124
124
  output.end_statement()
125
- needs_yield = output.options.js_version < 6 and module.baselib['yield']
126
- if needs_yield:
127
- output.dump_yield()
128
125
  # output the baselib
129
126
  if not output.options.baselib_plain:
130
127
  raise ValueError('The baselib is missing! Remember to set the baselib_plain field on the options for OutputStream')
@@ -186,7 +183,7 @@ def print_top_level(self, output):
186
183
  write_imports(self, output)
187
184
  write_main_name(output)
188
185
 
189
- declare_vars(self.localvars, output)
186
+ declare_vars(self.localvars, output, "var" if output.options.repl_mode else "let")
190
187
  display_body(self.body, True, output)
191
188
  if self.comments_after and self.comments_after.length:
192
189
  output_comments(self.comments_after, output)