Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/python-wasm
Path: blob/main/python/pylang/src/output/modules.py
1398 views
1
# vim:fileencoding=utf-8
2
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
# globals: writefile
4
from __python__ import hash_literals
5
6
from output.statements import declare_vars, display_body
7
from output.stream import OutputStream
8
from output.utils import create_doctring
9
from output.comments import print_comments, output_comments
10
from output.functions import set_module_name
11
from parse import get_compiler_version
12
from utils import cache_file_name
13
14
15
def write_imports(module, output):
16
imports = []
17
for import_id in Object.keys(module.imports):
18
imports.push(module.imports[import_id])
19
20
def compare(a, b):
21
a, b = a.import_order, b.import_order
22
return -1 if a < b else (1 if a > b else 0)
23
24
imports.sort(compare)
25
if imports.length > 1:
26
output.indent()
27
output.print('var ρσ_modules = {};')
28
output.newline()
29
30
# Declare all variable names exported from the modules as global symbols
31
nonlocalvars = {}
32
for module_ in imports:
33
for name in module_.nonlocalvars:
34
nonlocalvars[name] = True
35
nonlocalvars = Object.getOwnPropertyNames(nonlocalvars).join(', ')
36
if nonlocalvars.length:
37
output.indent()
38
output.print('var ' + nonlocalvars)
39
output.semicolon()
40
output.newline()
41
42
# Create the module objects
43
for module_ in imports:
44
module_id = module_.module_id
45
if module_id is not '__main__':
46
output.indent()
47
if module_id.indexOf('.') is -1:
48
output.print('ρσ_modules.' + module_id)
49
else:
50
output.print('ρσ_modules["' + module_id + '"]')
51
output.space(), output.print('='), output.space(), output.print(
52
'{}')
53
output.end_statement()
54
55
# Output module code
56
for module_ in imports:
57
if module_.module_id is not '__main__':
58
print_module(module_, output)
59
60
61
def write_main_name(output):
62
if output.options.write_name:
63
output.newline()
64
output.indent()
65
output.print('var __name__ = "__main__"')
66
output.semicolon()
67
output.newline()
68
output.newline()
69
70
71
def declare_exports(module_id, exports, output, docstrings):
72
seen = {}
73
if output.options.keep_docstrings and docstrings and docstrings.length:
74
exports.push({'name': '__doc__', 'refname': 'ρσ_module_doc__'})
75
output.newline(), output.indent()
76
v = 'var'
77
output.assign(v + ' ρσ_module_doc__'), output.print(
78
JSON.stringify(create_doctring(docstrings)))
79
output.end_statement()
80
output.newline()
81
for symbol in exports:
82
if not Object.prototype.hasOwnProperty.call(seen, symbol.name):
83
output.indent()
84
if module_id.indexOf('.') is -1:
85
output.print('ρσ_modules.' + module_id + '.' + symbol.name)
86
else:
87
output.print('ρσ_modules["' + module_id + '"].' + symbol.name)
88
output.space(), output.print('='), output.space(), output.print(
89
symbol.refname or symbol.name)
90
seen[symbol.name] = True
91
output.end_statement()
92
93
94
def prologue(module, output):
95
# any code that should appear before the main body
96
if output.options.omit_baselib:
97
return
98
output.indent()
99
v = 'var'
100
output.print(v), output.space()
101
output.spaced.apply(output, ((
102
'ρσ_iterator_symbol = (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") ? Symbol.iterator : "iterator-Symbol-5d0927e5554349048cf0e3762a228256"'
103
.split(' '))))
104
output.end_statement()
105
output.indent(), output.print(v), output.space()
106
output.spaced.apply(output, ((
107
'ρσ_kwargs_symbol = (typeof Symbol === "function") ? Symbol("kwargs-object") : "kwargs-object-Symbol-5d0927e5554349048cf0e3762a228256"'
108
.split(' '))))
109
output.end_statement()
110
output.indent(), output.spaced(
111
'var', 'ρσ_cond_temp,', 'ρσ_expr_temp,',
112
'ρσ_last_exception'), output.end_statement()
113
output.indent(), output.spaced('var', 'ρσ_object_counter', '=',
114
'0'), output.end_statement()
115
# Needed for Chrome < 51 and Edge as of August 2016
116
output.indent(), output.spaced(
117
'if(', 'typeof', 'HTMLCollection', '!==', '"undefined"', '&&',
118
'typeof', 'Symbol', '===', '"function")',
119
'NodeList.prototype[Symbol.iterator]', '=',
120
'HTMLCollection.prototype[Symbol.iterator]', '=',
121
'NamedNodeMap.prototype[Symbol.iterator]', '=',
122
'Array.prototype[Symbol.iterator]')
123
output.end_statement()
124
# output the baselib
125
if not output.options.baselib_plain:
126
raise ValueError(
127
'The baselib is missing! Remember to set the baselib_plain field on the options for OutputStream'
128
)
129
output.print(output.options.baselib_plain)
130
output.end_statement()
131
132
133
def print_top_level(self, output):
134
set_module_name(self.module_id)
135
is_main = self.module_id is '__main__'
136
137
def write_docstrings():
138
if is_main and output.options.keep_docstrings and self.docstrings and self.docstrings.length:
139
output.newline(), output.indent()
140
v = 'var'
141
output.assign(v + ' ρσ_module_doc__'), output.print(
142
JSON.stringify(create_doctring(self.docstrings)))
143
output.end_statement()
144
145
if output.options.private_scope and is_main:
146
147
def f_main_function():
148
output.print("function()")
149
150
def f_full_function():
151
# strict mode is more verbose about errors, and less forgiving about them
152
# kind of like Python
153
output.indent()
154
output.print('"use strict"')
155
output.end_statement()
156
157
prologue(self, output)
158
write_imports(self, output)
159
output.newline()
160
output.indent()
161
162
def f_function():
163
output.print("function()")
164
165
def f_body():
166
write_main_name(output)
167
output.newline()
168
declare_vars(self.localvars, output)
169
display_body(self.body, True, output)
170
output.newline()
171
write_docstrings()
172
if self.comments_after and self.comments_after.length:
173
output.indent()
174
output_comments(self.comments_after, output)
175
output.newline()
176
177
output.with_block(f_body)
178
179
output.with_parens(f_function)
180
181
output.print("();")
182
output.newline()
183
184
output.with_block(f_full_function)
185
186
output.with_parens(f_main_function)
187
output.print("();")
188
output.print("")
189
else:
190
if is_main:
191
prologue(self, output)
192
write_imports(self, output)
193
write_main_name(output)
194
195
declare_vars(self.localvars, output)
196
display_body(self.body, True, output)
197
if self.comments_after and self.comments_after.length:
198
output_comments(self.comments_after, output)
199
set_module_name()
200
201
202
def print_module(self, output):
203
set_module_name(self.module_id)
204
205
def output_module(output):
206
declare_vars(self.localvars, output)
207
display_body(self.body, True, output)
208
declare_exports(self.module_id, self.exports, output, self.docstrings)
209
210
output.newline()
211
output.indent()
212
213
def f_print_module():
214
output.print("function()")
215
216
def dump_the_logic_of_this_module():
217
print_comments(self, output)
218
if output.options.write_name:
219
output.indent()
220
output.print('var ')
221
output.assign('__name__')
222
output.print('"' + self.module_id + '"')
223
output.semicolon()
224
output.newline()
225
226
def output_key(beautify, keep_docstrings):
227
return 'beautify:' + beautify + ' keep_docstrings:' + keep_docstrings
228
229
okey = output_key(output.options.beautify,
230
output.options.keep_docstrings)
231
if self.is_cached and okey in self.outputs:
232
output.print(self.outputs[okey])
233
else:
234
output_module(output)
235
if self.srchash and self.filename:
236
cached = {
237
'version': get_compiler_version(),
238
'signature': self.srchash,
239
'classes': {},
240
'baselib': self.baselib,
241
'nonlocalvars': self.nonlocalvars,
242
'imported_module_ids': self.imported_module_ids,
243
'exports': [],
244
'outputs': {},
245
'discard_asserts': bool(output.options.discard_asserts)
246
}
247
for cname in Object.keys(self.classes):
248
cobj = self.classes[cname]
249
cached.classes[cname] = {
250
'name': {
251
'name': cobj.name.name
252
},
253
'static': cobj.static,
254
'bound': cobj.bound,
255
'classvars': cobj.classvars
256
}
257
for symdef in self.exports:
258
cached.exports.push({'name': symdef.name})
259
for beautify in [True, False]:
260
for keep_docstrings in [True, False]:
261
co = OutputStream({
262
'beautify':
263
beautify,
264
'keep_docstrings':
265
keep_docstrings,
266
'write_name':
267
False,
268
'discard_asserts':
269
output.options.discard_asserts
270
})
271
co.with_indent(output.indentation(),
272
lambda: output_module(co))
273
raw = co.get()
274
cached.outputs[output_key(beautify,
275
keep_docstrings)] = raw
276
cached_name = cache_file_name(
277
self.filename, output.options.module_cache_dir)
278
try:
279
if cached_name:
280
writefile(cached_name,
281
JSON.stringify(cached, None, '\t'))
282
except Error as e:
283
console.error('Failed to write output cache file:',
284
cached_name, 'with error:', e)
285
286
output.with_block(dump_the_logic_of_this_module)
287
288
output.with_parens(f_print_module)
289
output.print("()")
290
output.semicolon()
291
output.newline()
292
set_module_name()
293
294
295
def print_imports(container, output):
296
is_first_aname = True
297
298
def add_aname(aname, key, from_import):
299
nonlocal is_first_aname
300
if is_first_aname:
301
is_first_aname = False
302
else:
303
output.indent()
304
output.print('var ')
305
output.assign(aname)
306
if key.indexOf('.') is -1:
307
output.print('ρσ_modules.'), output.print(key)
308
else:
309
output.print('ρσ_modules["'), output.print(key), output.print('"]')
310
if from_import:
311
output.print('.')
312
output.print(from_import)
313
output.end_statement()
314
315
for self in container.imports:
316
if self.argnames:
317
# A from import
318
for argname in self.argnames:
319
akey = argname.alias.name if argname.alias else argname.name
320
add_aname(akey, self.key, argname.name)
321
else:
322
if self.alias:
323
add_aname(self.alias.name, self.key, False)
324
else:
325
parts = self.key.split('.')
326
for i, part in enumerate(parts):
327
if i is 0:
328
add_aname(part, part, False)
329
else:
330
q = parts[:i + 1].join('.')
331
output.indent()
332
output.spaced(q, '=', 'ρσ_modules["' + q + '"]')
333
output.end_statement()
334
335