rapydscript-ns 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agignore +1 -0
- package/.gitattributes +4 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/web-repl-page-deploy.yml +42 -0
- package/=template.pyj +5 -0
- package/CHANGELOG.md +456 -0
- package/CONTRIBUTORS +13 -0
- package/HACKING.md +103 -0
- package/LICENSE +24 -0
- package/README.md +2512 -0
- package/TODO.md +327 -0
- package/add-toc-to-readme +2 -0
- package/bin/export +75 -0
- package/bin/rapydscript +70 -0
- package/bin/web-repl-export +102 -0
- package/build +3 -0
- package/package.json +46 -0
- package/publish.py +37 -0
- package/release/baselib-plain-pretty.js +4370 -0
- package/release/baselib-plain-ugly.js +3 -0
- package/release/compiler.js +18394 -0
- package/release/signatures.json +31 -0
- package/session.vim +4 -0
- package/setup.cfg +2 -0
- package/src/ast.pyj +1356 -0
- package/src/baselib-builtins.pyj +279 -0
- package/src/baselib-containers.pyj +723 -0
- package/src/baselib-errors.pyj +37 -0
- package/src/baselib-internal.pyj +421 -0
- package/src/baselib-itertools.pyj +97 -0
- package/src/baselib-str.pyj +798 -0
- package/src/compiler.pyj +36 -0
- package/src/errors.pyj +30 -0
- package/src/lib/aes.pyj +646 -0
- package/src/lib/collections.pyj +695 -0
- package/src/lib/elementmaker.pyj +83 -0
- package/src/lib/encodings.pyj +126 -0
- package/src/lib/functools.pyj +148 -0
- package/src/lib/gettext.pyj +569 -0
- package/src/lib/itertools.pyj +580 -0
- package/src/lib/math.pyj +193 -0
- package/src/lib/numpy.pyj +2101 -0
- package/src/lib/operator.pyj +11 -0
- package/src/lib/pythonize.pyj +20 -0
- package/src/lib/random.pyj +118 -0
- package/src/lib/re.pyj +470 -0
- package/src/lib/traceback.pyj +63 -0
- package/src/lib/uuid.pyj +77 -0
- package/src/monaco-language-service/analyzer.js +526 -0
- package/src/monaco-language-service/builtins.js +543 -0
- package/src/monaco-language-service/completions.js +498 -0
- package/src/monaco-language-service/diagnostics.js +643 -0
- package/src/monaco-language-service/dts.js +550 -0
- package/src/monaco-language-service/hover.js +121 -0
- package/src/monaco-language-service/index.js +386 -0
- package/src/monaco-language-service/scope.js +162 -0
- package/src/monaco-language-service/signature.js +144 -0
- package/src/output/__init__.pyj +0 -0
- package/src/output/classes.pyj +296 -0
- package/src/output/codegen.pyj +492 -0
- package/src/output/comments.pyj +45 -0
- package/src/output/exceptions.pyj +105 -0
- package/src/output/functions.pyj +491 -0
- package/src/output/literals.pyj +109 -0
- package/src/output/loops.pyj +444 -0
- package/src/output/modules.pyj +329 -0
- package/src/output/operators.pyj +429 -0
- package/src/output/statements.pyj +463 -0
- package/src/output/stream.pyj +309 -0
- package/src/output/treeshake.pyj +182 -0
- package/src/output/utils.pyj +72 -0
- package/src/parse.pyj +3106 -0
- package/src/string_interpolation.pyj +72 -0
- package/src/tokenizer.pyj +702 -0
- package/src/unicode_aliases.pyj +576 -0
- package/src/utils.pyj +192 -0
- package/test/_import_one.pyj +37 -0
- package/test/_import_two/__init__.pyj +11 -0
- package/test/_import_two/level2/__init__.pyj +0 -0
- package/test/_import_two/level2/deep.pyj +4 -0
- package/test/_import_two/other.pyj +6 -0
- package/test/_import_two/sub.pyj +13 -0
- package/test/aes_vectors.pyj +421 -0
- package/test/annotations.pyj +80 -0
- package/test/baselib.pyj +319 -0
- package/test/classes.pyj +452 -0
- package/test/collections.pyj +152 -0
- package/test/decorators.pyj +77 -0
- package/test/dict_spread.pyj +76 -0
- package/test/docstrings.pyj +39 -0
- package/test/elementmaker_test.pyj +45 -0
- package/test/ellipsis.pyj +49 -0
- package/test/functions.pyj +151 -0
- package/test/generators.pyj +41 -0
- package/test/generic.pyj +370 -0
- package/test/imports.pyj +72 -0
- package/test/internationalization.pyj +73 -0
- package/test/lint.pyj +164 -0
- package/test/loops.pyj +85 -0
- package/test/numpy.pyj +734 -0
- package/test/omit_function_metadata.pyj +20 -0
- package/test/regexp.pyj +55 -0
- package/test/repl.pyj +121 -0
- package/test/scoped_flags.pyj +76 -0
- package/test/starargs.pyj +506 -0
- package/test/starred_assign.pyj +104 -0
- package/test/str.pyj +198 -0
- package/test/subscript_tuple.pyj +53 -0
- package/test/unit/fixtures/fibonacci_expected.js +46 -0
- package/test/unit/index.js +2989 -0
- package/test/unit/language-service-builtins.js +815 -0
- package/test/unit/language-service-completions.js +1067 -0
- package/test/unit/language-service-dts.js +543 -0
- package/test/unit/language-service-hover.js +455 -0
- package/test/unit/language-service-scope.js +833 -0
- package/test/unit/language-service-signature.js +458 -0
- package/test/unit/language-service.js +705 -0
- package/test/unit/run-language-service.js +41 -0
- package/test/unit/web-repl.js +484 -0
- package/tools/build-language-service.js +190 -0
- package/tools/cli.js +547 -0
- package/tools/compile.js +219 -0
- package/tools/compiler.js +108 -0
- package/tools/completer.js +131 -0
- package/tools/embedded_compiler.js +251 -0
- package/tools/export.js +316 -0
- package/tools/gettext.js +185 -0
- package/tools/ini.js +65 -0
- package/tools/lint.js +705 -0
- package/tools/msgfmt.js +187 -0
- package/tools/repl.js +223 -0
- package/tools/self.js +162 -0
- package/tools/test.js +118 -0
- package/tools/utils.js +128 -0
- package/tools/web_repl.js +95 -0
- package/try +41 -0
- package/web-repl/env.js +74 -0
- package/web-repl/index.html +163 -0
- package/web-repl/language-service.js +4084 -0
- package/web-repl/main.js +254 -0
- package/web-repl/prism.css +139 -0
- package/web-repl/prism.js +113 -0
- package/web-repl/rapydscript.js +435 -0
- package/web-repl/sha1.js +25 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
# globals:regenerate
|
|
4
|
+
from __python__ import hash_literals
|
|
5
|
+
|
|
6
|
+
from ast import AST_ClassCall, AST_New, has_calls, AST_Dot, AST_SymbolRef, is_node_type
|
|
7
|
+
from output.stream import OutputStream
|
|
8
|
+
from output.statements import print_bracketed
|
|
9
|
+
from output.utils import create_doctring
|
|
10
|
+
from output.operators import print_getattr
|
|
11
|
+
|
|
12
|
+
anonfunc = 'ρσ_anonfunc'
|
|
13
|
+
module_name = 'null'
|
|
14
|
+
|
|
15
|
+
def set_module_name(x):
|
|
16
|
+
nonlocal module_name
|
|
17
|
+
module_name = '"' + x + '"' if x else 'null'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Function definition {{{
|
|
21
|
+
|
|
22
|
+
def decorate(decorators, output, func):
|
|
23
|
+
pos = 0
|
|
24
|
+
def wrap():
|
|
25
|
+
nonlocal pos
|
|
26
|
+
if pos < decorators.length:
|
|
27
|
+
decorators[pos].expression.print(output)
|
|
28
|
+
pos += 1
|
|
29
|
+
output.with_parens(def():
|
|
30
|
+
wrap()
|
|
31
|
+
)
|
|
32
|
+
else:
|
|
33
|
+
func()
|
|
34
|
+
wrap()
|
|
35
|
+
|
|
36
|
+
def function_args(argnames, output, strip_first):
|
|
37
|
+
output.with_parens(def():
|
|
38
|
+
if argnames and argnames.length and (argnames.is_simple_func is True or argnames.is_simple_func is undefined):
|
|
39
|
+
for i, arg in enumerate((argnames.slice(1) if strip_first else argnames)):
|
|
40
|
+
if i:
|
|
41
|
+
output.comma()
|
|
42
|
+
arg.print(output)
|
|
43
|
+
)
|
|
44
|
+
output.space()
|
|
45
|
+
|
|
46
|
+
def function_preamble(node, output, offset):
|
|
47
|
+
a = node.argnames
|
|
48
|
+
if not a or a.is_simple_func:
|
|
49
|
+
return
|
|
50
|
+
# If this function has optional parameters/*args/**kwargs declare it differently
|
|
51
|
+
fname = node.name.name if node.name else anonfunc
|
|
52
|
+
kw = 'arguments[arguments.length-1]'
|
|
53
|
+
# Define all formal parameters
|
|
54
|
+
positional_count = 0
|
|
55
|
+
for c, arg in enumerate(a):
|
|
56
|
+
i = c - offset
|
|
57
|
+
if i >= 0:
|
|
58
|
+
output.indent()
|
|
59
|
+
output.print("var")
|
|
60
|
+
output.space()
|
|
61
|
+
output.assign(arg)
|
|
62
|
+
if arg.kwonly:
|
|
63
|
+
# Keyword-only params: initialize from defaults or undefined; read from kwargs later
|
|
64
|
+
if Object.prototype.hasOwnProperty.call(a.defaults, arg.name):
|
|
65
|
+
output.print(fname + '.__defaults__.'), arg.print(output)
|
|
66
|
+
else:
|
|
67
|
+
output.print('undefined')
|
|
68
|
+
else:
|
|
69
|
+
positional_count += 1
|
|
70
|
+
if Object.prototype.hasOwnProperty.call(a.defaults, arg.name):
|
|
71
|
+
output.spaced('(arguments[' + i + ']', '===', 'undefined', '||',
|
|
72
|
+
'(', i, '===', 'arguments.length-1', '&&', kw, '!==', 'null', '&&', 'typeof', kw, '===', '"object"', '&&',
|
|
73
|
+
kw, '[ρσ_kwargs_symbol]', '===', 'true))', '?', '')
|
|
74
|
+
output.print(fname + '.__defaults__.'), arg.print(output)
|
|
75
|
+
output.space(), output.print(':'), output.space()
|
|
76
|
+
output.print('arguments[' + i + ']')
|
|
77
|
+
else:
|
|
78
|
+
output.spaced('(', i, '===', 'arguments.length-1', '&&', kw, '!==', 'null', '&&', 'typeof', kw, '===', '"object"', '&&',
|
|
79
|
+
kw, '[ρσ_kwargs_symbol]', '===', 'true)', '?', 'undefined', ':', '')
|
|
80
|
+
output.print('arguments[' + i + ']')
|
|
81
|
+
output.end_statement()
|
|
82
|
+
if a.kwargs or a.has_defaults or a.bare_star:
|
|
83
|
+
# Look for an options object
|
|
84
|
+
kw = a.kwargs.name if a.kwargs else 'ρσ_kwargs_obj'
|
|
85
|
+
output.indent()
|
|
86
|
+
output.spaced('var', kw, '=', 'arguments[arguments.length-1]')
|
|
87
|
+
output.end_statement()
|
|
88
|
+
# Ensure kwargs is the options object
|
|
89
|
+
output.indent()
|
|
90
|
+
output.spaced('if', '(' + kw, '===', 'null', '||', 'typeof', kw, '!==', '"object"', '||', kw, '[ρσ_kwargs_symbol]', '!==', 'true)', kw, '=', '{}')
|
|
91
|
+
output.end_statement()
|
|
92
|
+
# Read values from the kwargs object for non-positional-only formal parameters with defaults
|
|
93
|
+
if a.has_defaults:
|
|
94
|
+
for dname in Object.keys(a.defaults):
|
|
95
|
+
# Skip positional-only params: they must not be passed by keyword name
|
|
96
|
+
is_posonly = False
|
|
97
|
+
for v'var qi = 0; qi < (a.posonly_count || 0); qi++':
|
|
98
|
+
if a[qi].name is dname:
|
|
99
|
+
is_posonly = True
|
|
100
|
+
break
|
|
101
|
+
if is_posonly:
|
|
102
|
+
continue
|
|
103
|
+
# Skip kwonly params here; they are handled in the kwonly loop below
|
|
104
|
+
is_kwonly = False
|
|
105
|
+
for v'var ki = 0; ki < a.length; ki++':
|
|
106
|
+
if a[ki].name is dname and a[ki].kwonly:
|
|
107
|
+
is_kwonly = True
|
|
108
|
+
break
|
|
109
|
+
if is_kwonly:
|
|
110
|
+
continue
|
|
111
|
+
output.indent()
|
|
112
|
+
output.spaced('if', '(Object.prototype.hasOwnProperty.call(' + kw + ',', '"' + dname + '"))')
|
|
113
|
+
output.with_block(def():
|
|
114
|
+
output.indent()
|
|
115
|
+
output.spaced(dname, '=', kw + '.' + dname)
|
|
116
|
+
output.end_statement()
|
|
117
|
+
if a.kwargs:
|
|
118
|
+
output.indent()
|
|
119
|
+
output.spaced('delete', kw + '.' + dname)
|
|
120
|
+
output.end_statement()
|
|
121
|
+
)
|
|
122
|
+
output.newline()
|
|
123
|
+
# Read keyword-only params from the kwargs object (with or without defaults)
|
|
124
|
+
if a.bare_star:
|
|
125
|
+
for arg in a:
|
|
126
|
+
if not arg.kwonly:
|
|
127
|
+
continue
|
|
128
|
+
aname = arg.name
|
|
129
|
+
output.indent()
|
|
130
|
+
output.spaced('if', '(Object.prototype.hasOwnProperty.call(' + kw + ',', '"' + aname + '"))')
|
|
131
|
+
output.with_block(def():
|
|
132
|
+
output.indent()
|
|
133
|
+
output.spaced(aname, '=', kw + '.' + aname)
|
|
134
|
+
output.end_statement()
|
|
135
|
+
if a.kwargs:
|
|
136
|
+
output.indent()
|
|
137
|
+
output.spaced('delete', kw + '.' + aname)
|
|
138
|
+
output.end_statement()
|
|
139
|
+
)
|
|
140
|
+
output.newline()
|
|
141
|
+
|
|
142
|
+
if a.starargs is not undefined:
|
|
143
|
+
# Define the *args parameter, putting in whatever is left after assigning the formal parameters and the options object
|
|
144
|
+
nargs = a.length - offset
|
|
145
|
+
output.indent()
|
|
146
|
+
output.spaced('var', a.starargs.name, '=', 'Array.prototype.slice.call(arguments,', nargs + ')')
|
|
147
|
+
output.end_statement()
|
|
148
|
+
# Remove the options object, if present
|
|
149
|
+
output.indent()
|
|
150
|
+
output.spaced('if', '(' + kw, '!==', 'null', '&&', 'typeof', kw, '===', '"object"', '&&', kw, '[ρσ_kwargs_symbol]', '===', 'true)', a.starargs.name)
|
|
151
|
+
output.print('.pop()')
|
|
152
|
+
output.end_statement()
|
|
153
|
+
|
|
154
|
+
def has_annotations(self):
|
|
155
|
+
if self.return_annotation:
|
|
156
|
+
return True
|
|
157
|
+
for arg in self.argnames:
|
|
158
|
+
if arg.annotation:
|
|
159
|
+
return True
|
|
160
|
+
return False
|
|
161
|
+
|
|
162
|
+
def function_annotation(self, output, strip_first, name):
|
|
163
|
+
if output.options.omit_function_metadata:
|
|
164
|
+
return
|
|
165
|
+
fname = name or (self.name.name if self.name else anonfunc)
|
|
166
|
+
props = Object.create(None)
|
|
167
|
+
|
|
168
|
+
# Create __annotations__
|
|
169
|
+
if has_annotations(self):
|
|
170
|
+
props.__annotations__ = def():
|
|
171
|
+
output.print('{')
|
|
172
|
+
if self.argnames and self.argnames.length:
|
|
173
|
+
for i, arg in enumerate(self.argnames):
|
|
174
|
+
if arg.annotation:
|
|
175
|
+
arg.print(output)
|
|
176
|
+
output.print(':'), output.space()
|
|
177
|
+
arg.annotation.print(output)
|
|
178
|
+
if i < self.argnames.length - 1 or self.return_annotation:
|
|
179
|
+
output.comma()
|
|
180
|
+
if self.return_annotation:
|
|
181
|
+
output.print('return:'), output.space()
|
|
182
|
+
self.return_annotation.print(output)
|
|
183
|
+
output.print('}')
|
|
184
|
+
|
|
185
|
+
# Create __defaults__
|
|
186
|
+
defaults = self.argnames.defaults
|
|
187
|
+
dkeys = Object.keys(self.argnames.defaults)
|
|
188
|
+
if dkeys.length:
|
|
189
|
+
props.__defaults__ = def():
|
|
190
|
+
output.print('{')
|
|
191
|
+
for i, k in enumerate(dkeys):
|
|
192
|
+
output.print(k + ':'), defaults[k].print(output)
|
|
193
|
+
if i is not dkeys.length - 1:
|
|
194
|
+
output.comma()
|
|
195
|
+
output.print('}')
|
|
196
|
+
|
|
197
|
+
# Create __handles_kwarg_interpolation__
|
|
198
|
+
if not self.argnames.is_simple_func:
|
|
199
|
+
props.__handles_kwarg_interpolation__ = def():
|
|
200
|
+
output.print('true')
|
|
201
|
+
|
|
202
|
+
# Create __argnames__
|
|
203
|
+
# Positional-only params use null (prevents kwarg matching by name).
|
|
204
|
+
# Keyword-only params are omitted (they stay in the kwargs object and
|
|
205
|
+
# are read directly by the function preamble).
|
|
206
|
+
argnames_entries = v'[]'
|
|
207
|
+
for i, arg in enumerate(self.argnames):
|
|
208
|
+
if strip_first and i is 0:
|
|
209
|
+
continue
|
|
210
|
+
if arg.kwonly:
|
|
211
|
+
continue # kwonly params not in __argnames__
|
|
212
|
+
argnames_entries.push({'posonly': arg.posonly or False, 'name': arg.name})
|
|
213
|
+
if argnames_entries.length > 0:
|
|
214
|
+
props.__argnames__ = def():
|
|
215
|
+
output.print('[')
|
|
216
|
+
for ei, entry in enumerate(argnames_entries):
|
|
217
|
+
if entry.posonly:
|
|
218
|
+
output.print('null')
|
|
219
|
+
else:
|
|
220
|
+
output.print(JSON.stringify(entry.name))
|
|
221
|
+
if ei is not argnames_entries.length - 1:
|
|
222
|
+
output.comma()
|
|
223
|
+
output.print(']')
|
|
224
|
+
|
|
225
|
+
# Create __doc__
|
|
226
|
+
if output.options.keep_docstrings and self.docstrings and self.docstrings.length:
|
|
227
|
+
props.__doc__ = def():
|
|
228
|
+
output.print(JSON.stringify(create_doctring(self.docstrings)))
|
|
229
|
+
|
|
230
|
+
props.__module__ = def():
|
|
231
|
+
output.print(module_name)
|
|
232
|
+
|
|
233
|
+
names = Object.keys(props)
|
|
234
|
+
output.indent()
|
|
235
|
+
# Only define the properties if they were not already defined, which
|
|
236
|
+
# can happen if the function definition is inside a loop, for example.
|
|
237
|
+
output.spaced('if', '(!' + fname + '.' + names[0] + ')', 'Object.defineProperties(' + fname)
|
|
238
|
+
output.comma()
|
|
239
|
+
output.with_block(def():
|
|
240
|
+
for v'var i = 0; i < names.length; i++':
|
|
241
|
+
name = names[i]
|
|
242
|
+
output.indent(), output.spaced(name, ':', '{value:', ''), props[name](), output.print('}')
|
|
243
|
+
if i < names.length - 1:
|
|
244
|
+
output.print(',')
|
|
245
|
+
output.newline()
|
|
246
|
+
)
|
|
247
|
+
output.print(')'), output.end_statement()
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def function_definition(self, output, strip_first, as_expression):
|
|
251
|
+
as_expression = as_expression or self.is_expression or self.is_anonymous
|
|
252
|
+
if as_expression:
|
|
253
|
+
orig_indent = output.indentation()
|
|
254
|
+
output.set_indentation(output.next_indent())
|
|
255
|
+
output.spaced('(function()', '{'), output.newline()
|
|
256
|
+
output.indent(), output.spaced('var', anonfunc, '='), output.space()
|
|
257
|
+
if self.is_async:
|
|
258
|
+
output.print("async"), output.space()
|
|
259
|
+
output.print("function"), output.space()
|
|
260
|
+
if self.name:
|
|
261
|
+
self.name.print(output)
|
|
262
|
+
|
|
263
|
+
if self.is_generator:
|
|
264
|
+
output.print('()'), output.space()
|
|
265
|
+
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)
|
|
281
|
+
output.newline()
|
|
282
|
+
output.indent()
|
|
283
|
+
output.spaced('var', 'result', '=', 'js_generator.apply(this,', 'arguments)')
|
|
284
|
+
output.end_statement()
|
|
285
|
+
# Python's generator objects use a separate method to send data to the generator
|
|
286
|
+
output.indent()
|
|
287
|
+
output.spaced('result.send', '=', 'result.next')
|
|
288
|
+
output.end_statement()
|
|
289
|
+
output.indent()
|
|
290
|
+
output.spaced('return', 'result')
|
|
291
|
+
output.end_statement()
|
|
292
|
+
)
|
|
293
|
+
else:
|
|
294
|
+
function_args(self.argnames, output, strip_first)
|
|
295
|
+
print_bracketed(self, output, True, function_preamble)
|
|
296
|
+
|
|
297
|
+
if as_expression:
|
|
298
|
+
output.end_statement()
|
|
299
|
+
function_annotation(self, output, strip_first, anonfunc)
|
|
300
|
+
output.indent(), output.spaced('return', anonfunc), output.end_statement()
|
|
301
|
+
output.set_indentation(orig_indent)
|
|
302
|
+
output.indent(), output.print("})()")
|
|
303
|
+
|
|
304
|
+
def print_function(output):
|
|
305
|
+
self = this
|
|
306
|
+
if self.decorators and self.decorators.length:
|
|
307
|
+
output.print("var")
|
|
308
|
+
output.space()
|
|
309
|
+
output.assign(self.name.name)
|
|
310
|
+
decorate(self.decorators, output, def():function_definition(self, output, False, True);)
|
|
311
|
+
output.end_statement()
|
|
312
|
+
else:
|
|
313
|
+
function_definition(self, output, False)
|
|
314
|
+
if not self.is_expression and not self.is_anonymous:
|
|
315
|
+
output.end_statement()
|
|
316
|
+
function_annotation(self, output, False)
|
|
317
|
+
# }}}
|
|
318
|
+
|
|
319
|
+
# Function call {{{
|
|
320
|
+
|
|
321
|
+
def find_this(expression):
|
|
322
|
+
if is_node_type(expression, AST_Dot):
|
|
323
|
+
return expression.expression
|
|
324
|
+
if not is_node_type(expression, AST_SymbolRef):
|
|
325
|
+
return expression
|
|
326
|
+
|
|
327
|
+
def print_this(expression, output):
|
|
328
|
+
obj = find_this(expression)
|
|
329
|
+
if obj:
|
|
330
|
+
obj.print(output)
|
|
331
|
+
else:
|
|
332
|
+
output.print('this')
|
|
333
|
+
|
|
334
|
+
def print_function_call(self, output):
|
|
335
|
+
is_prototype_call = False
|
|
336
|
+
|
|
337
|
+
def print_function_name(no_call):
|
|
338
|
+
nonlocal is_prototype_call
|
|
339
|
+
if is_node_type(self, AST_ClassCall):
|
|
340
|
+
# class methods are called through the prototype unless static
|
|
341
|
+
if self.static:
|
|
342
|
+
self.class.print(output)
|
|
343
|
+
output.print(".")
|
|
344
|
+
output.print(self.method)
|
|
345
|
+
else:
|
|
346
|
+
is_prototype_call = True
|
|
347
|
+
self.class.print(output)
|
|
348
|
+
output.print(".prototype.")
|
|
349
|
+
output.print(self.method)
|
|
350
|
+
if not no_call:
|
|
351
|
+
output.print(".call")
|
|
352
|
+
else:
|
|
353
|
+
if not is_repeatable:
|
|
354
|
+
output.print('ρσ_expr_temp')
|
|
355
|
+
if is_node_type(self.expression, AST_Dot):
|
|
356
|
+
print_getattr(self.expression, output, True)
|
|
357
|
+
else:
|
|
358
|
+
# Bare print(...) → ρσ_print(...) in kwargs/starargs context
|
|
359
|
+
if is_node_type(self.expression, AST_SymbolRef) and self.expression.name is 'print':
|
|
360
|
+
output.print('ρσ_print')
|
|
361
|
+
else:
|
|
362
|
+
self.expression.print(output)
|
|
363
|
+
|
|
364
|
+
def print_kwargs():
|
|
365
|
+
output.print('ρσ_desugar_kwargs(')
|
|
366
|
+
if has_kwarg_items:
|
|
367
|
+
for i, kwname in enumerate(self.args.kwarg_items):
|
|
368
|
+
if i > 0:
|
|
369
|
+
output.print(',')
|
|
370
|
+
output.space()
|
|
371
|
+
kwname.print(output)
|
|
372
|
+
if has_kwarg_formals:
|
|
373
|
+
output.print(',')
|
|
374
|
+
output.space()
|
|
375
|
+
|
|
376
|
+
if has_kwarg_formals:
|
|
377
|
+
output.print('{')
|
|
378
|
+
for i, pair in enumerate(self.args.kwargs):
|
|
379
|
+
if i: output.comma()
|
|
380
|
+
pair[0].print(output)
|
|
381
|
+
output.print(':')
|
|
382
|
+
output.space()
|
|
383
|
+
pair[1].print(output)
|
|
384
|
+
output.print('}')
|
|
385
|
+
output.print(')')
|
|
386
|
+
|
|
387
|
+
def print_new(apply):
|
|
388
|
+
output.print('ρσ_interpolate_kwargs_constructor.call(')
|
|
389
|
+
output.print('Object.create('), self.expression.print(output), output.print('.prototype)')
|
|
390
|
+
output.comma()
|
|
391
|
+
output.print('true' if apply else 'false')
|
|
392
|
+
output.comma()
|
|
393
|
+
|
|
394
|
+
def do_print_this():
|
|
395
|
+
if not is_repeatable:
|
|
396
|
+
output.print('ρσ_expr_temp')
|
|
397
|
+
else:
|
|
398
|
+
print_this(self.expression, output)
|
|
399
|
+
output.comma()
|
|
400
|
+
|
|
401
|
+
def print_positional_args():
|
|
402
|
+
# basic arguments
|
|
403
|
+
i = 0
|
|
404
|
+
while i < self.args.length:
|
|
405
|
+
expr = self.args[i]
|
|
406
|
+
is_first = i is 0
|
|
407
|
+
if not is_first:
|
|
408
|
+
output.print('.concat(')
|
|
409
|
+
if expr.is_array:
|
|
410
|
+
expr.print(output)
|
|
411
|
+
i += 1
|
|
412
|
+
else:
|
|
413
|
+
output.print('[')
|
|
414
|
+
while i < self.args.length and not self.args[i].is_array:
|
|
415
|
+
self.args[i].print(output)
|
|
416
|
+
if i + 1 < self.args.length and not self.args[i+1].is_array:
|
|
417
|
+
output.print(',')
|
|
418
|
+
output.space()
|
|
419
|
+
i += 1
|
|
420
|
+
output.print(']')
|
|
421
|
+
if not is_first:
|
|
422
|
+
output.print(')')
|
|
423
|
+
|
|
424
|
+
has_kwarg_items = self.args.kwarg_items and self.args.kwarg_items.length
|
|
425
|
+
has_kwarg_formals = self.args.kwargs and self.args.kwargs.length
|
|
426
|
+
has_kwargs = has_kwarg_items or has_kwarg_formals
|
|
427
|
+
is_new = is_node_type(self, AST_New)
|
|
428
|
+
is_repeatable = True
|
|
429
|
+
|
|
430
|
+
if is_new and not self.args.length and not has_kwargs and not self.args.starargs:
|
|
431
|
+
output.print('new'), output.space()
|
|
432
|
+
print_function_name()
|
|
433
|
+
return # new A is the same as new A() in javascript
|
|
434
|
+
|
|
435
|
+
if not has_kwargs and not self.args.starargs:
|
|
436
|
+
# A simple function call, do nothing special
|
|
437
|
+
if is_new:
|
|
438
|
+
output.print('new'), output.space()
|
|
439
|
+
# Bare print(...) → console.log(...) to avoid clobbering window.print
|
|
440
|
+
if not is_new and is_node_type(self.expression, AST_SymbolRef) and self.expression.name is 'print':
|
|
441
|
+
output.print('console.log')
|
|
442
|
+
else:
|
|
443
|
+
print_function_name()
|
|
444
|
+
output.with_parens(def():
|
|
445
|
+
for i, a in enumerate(self.args):
|
|
446
|
+
if i:
|
|
447
|
+
output.comma()
|
|
448
|
+
a.print(output)
|
|
449
|
+
)
|
|
450
|
+
return
|
|
451
|
+
|
|
452
|
+
is_repeatable = is_new or not has_calls(self.expression)
|
|
453
|
+
if not is_repeatable:
|
|
454
|
+
output.assign('(ρσ_expr_temp'), print_this(self.expression, output), output.comma()
|
|
455
|
+
|
|
456
|
+
if has_kwargs:
|
|
457
|
+
if is_new:
|
|
458
|
+
print_new(False)
|
|
459
|
+
else:
|
|
460
|
+
output.print('ρσ_interpolate_kwargs.call(')
|
|
461
|
+
do_print_this()
|
|
462
|
+
print_function_name(True)
|
|
463
|
+
output.comma()
|
|
464
|
+
else:
|
|
465
|
+
if is_new:
|
|
466
|
+
print_new(True)
|
|
467
|
+
print_function_name(True)
|
|
468
|
+
output.comma()
|
|
469
|
+
else:
|
|
470
|
+
print_function_name(True)
|
|
471
|
+
output.print('.apply(')
|
|
472
|
+
do_print_this()
|
|
473
|
+
|
|
474
|
+
if is_prototype_call and self.args.length > 1:
|
|
475
|
+
self.args.shift()
|
|
476
|
+
|
|
477
|
+
print_positional_args()
|
|
478
|
+
|
|
479
|
+
if has_kwargs:
|
|
480
|
+
if self.args.length:
|
|
481
|
+
output.print('.concat(')
|
|
482
|
+
output.print('[')
|
|
483
|
+
print_kwargs()
|
|
484
|
+
output.print(']')
|
|
485
|
+
if self.args.length:
|
|
486
|
+
output.print(')')
|
|
487
|
+
|
|
488
|
+
output.print(')')
|
|
489
|
+
if not is_repeatable:
|
|
490
|
+
output.print(')')
|
|
491
|
+
# }}}
|
|
@@ -0,0 +1,109 @@
|
|
|
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_Binary, AST_ObjectSpread, is_node_type
|
|
6
|
+
|
|
7
|
+
def print_array(self, output):
|
|
8
|
+
output.print('ρσ_list_decorate')
|
|
9
|
+
output.with_parens(def():
|
|
10
|
+
output.with_square(def():
|
|
11
|
+
a = self.elements
|
|
12
|
+
len_ = a.length
|
|
13
|
+
if len_ > 0:
|
|
14
|
+
output.space()
|
|
15
|
+
for i, exp in enumerate(a):
|
|
16
|
+
if i:
|
|
17
|
+
output.comma()
|
|
18
|
+
exp.print(output)
|
|
19
|
+
if len_ > 0:
|
|
20
|
+
output.space()
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def print_obj_literal(self, output):
|
|
26
|
+
output.with_parens(def():
|
|
27
|
+
output.print('function()')
|
|
28
|
+
output.with_block(def():
|
|
29
|
+
output.indent()
|
|
30
|
+
if self.is_pydict:
|
|
31
|
+
output.spaced.apply(output, 'var ρσ_d = ρσ_dict()'.split(' '))
|
|
32
|
+
else:
|
|
33
|
+
output.spaced('var', 'ρσ_d', '=', ('Object.create(null)' if self.is_jshash else '{}'))
|
|
34
|
+
output.end_statement()
|
|
35
|
+
for i, prop in enumerate(self.properties):
|
|
36
|
+
output.indent()
|
|
37
|
+
if is_node_type(prop, AST_ObjectSpread):
|
|
38
|
+
if self.is_pydict:
|
|
39
|
+
output.print('ρσ_d.update')
|
|
40
|
+
output.with_parens(def(): prop.value.print(output);)
|
|
41
|
+
else:
|
|
42
|
+
output.print('Object.assign')
|
|
43
|
+
output.with_parens(def():
|
|
44
|
+
output.print('ρσ_d')
|
|
45
|
+
output.print(','), output.space()
|
|
46
|
+
prop.value.print(output)
|
|
47
|
+
)
|
|
48
|
+
elif self.is_pydict:
|
|
49
|
+
output.print('ρσ_d.set')
|
|
50
|
+
output.with_parens(def():
|
|
51
|
+
prop.key.print(output)
|
|
52
|
+
output.print(','), output.space()
|
|
53
|
+
prop.value.print(output)
|
|
54
|
+
)
|
|
55
|
+
else:
|
|
56
|
+
output.print('ρσ_d')
|
|
57
|
+
output.with_square(def():prop.key.print(output);)
|
|
58
|
+
output.space(), output.print('='), output.space()
|
|
59
|
+
prop.value.print(output)
|
|
60
|
+
output.end_statement()
|
|
61
|
+
output.indent()
|
|
62
|
+
output.spaced('return', 'ρσ_d')
|
|
63
|
+
output.end_statement()
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
output.print('.call(this)')
|
|
67
|
+
|
|
68
|
+
def print_object(self, output):
|
|
69
|
+
if self.is_pydict:
|
|
70
|
+
if self.properties.length > 0:
|
|
71
|
+
print_obj_literal(self, output)
|
|
72
|
+
else:
|
|
73
|
+
output.print('ρσ_dict()')
|
|
74
|
+
else:
|
|
75
|
+
if self.properties.length > 0:
|
|
76
|
+
print_obj_literal(self, output)
|
|
77
|
+
else:
|
|
78
|
+
output.print("Object.create(null)" if self.is_jshash else '{}')
|
|
79
|
+
|
|
80
|
+
def print_set(self, output):
|
|
81
|
+
if self.items.length is 0:
|
|
82
|
+
output.print('ρσ_set()')
|
|
83
|
+
return
|
|
84
|
+
output.with_parens(def():
|
|
85
|
+
output.print('function()')
|
|
86
|
+
output.with_block(def():
|
|
87
|
+
output.indent()
|
|
88
|
+
output.spaced.apply(output, 'var s = ρσ_set()'.split(' '))
|
|
89
|
+
output.end_statement()
|
|
90
|
+
for item in self.items:
|
|
91
|
+
output.indent()
|
|
92
|
+
output.print('s.jsset.add')
|
|
93
|
+
output.with_parens(def():item.value.print(output);)
|
|
94
|
+
output.end_statement()
|
|
95
|
+
output.indent()
|
|
96
|
+
output.spaced('return', 's')
|
|
97
|
+
output.end_statement()
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
output.print('()')
|
|
101
|
+
|
|
102
|
+
def print_regexp(self, output):
|
|
103
|
+
str_ = self.value.toString()
|
|
104
|
+
if output.options.ascii_only:
|
|
105
|
+
str_ = output.to_ascii(str_)
|
|
106
|
+
output.print(str_)
|
|
107
|
+
p = output.parent()
|
|
108
|
+
if is_node_type(p, AST_Binary) and /^in/.test(p.operator) and p.left is self:
|
|
109
|
+
output.print(" ")
|