Path: blob/main/python/pylang/src/output/modules.py
1398 views
# vim:fileencoding=utf-81# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>2# globals: writefile3from __python__ import hash_literals45from output.statements import declare_vars, display_body6from output.stream import OutputStream7from output.utils import create_doctring8from output.comments import print_comments, output_comments9from output.functions import set_module_name10from parse import get_compiler_version11from utils import cache_file_name121314def write_imports(module, output):15imports = []16for import_id in Object.keys(module.imports):17imports.push(module.imports[import_id])1819def compare(a, b):20a, b = a.import_order, b.import_order21return -1 if a < b else (1 if a > b else 0)2223imports.sort(compare)24if imports.length > 1:25output.indent()26output.print('var ρσ_modules = {};')27output.newline()2829# Declare all variable names exported from the modules as global symbols30nonlocalvars = {}31for module_ in imports:32for name in module_.nonlocalvars:33nonlocalvars[name] = True34nonlocalvars = Object.getOwnPropertyNames(nonlocalvars).join(', ')35if nonlocalvars.length:36output.indent()37output.print('var ' + nonlocalvars)38output.semicolon()39output.newline()4041# Create the module objects42for module_ in imports:43module_id = module_.module_id44if module_id is not '__main__':45output.indent()46if module_id.indexOf('.') is -1:47output.print('ρσ_modules.' + module_id)48else:49output.print('ρσ_modules["' + module_id + '"]')50output.space(), output.print('='), output.space(), output.print(51'{}')52output.end_statement()5354# Output module code55for module_ in imports:56if module_.module_id is not '__main__':57print_module(module_, output)585960def write_main_name(output):61if output.options.write_name:62output.newline()63output.indent()64output.print('var __name__ = "__main__"')65output.semicolon()66output.newline()67output.newline()686970def declare_exports(module_id, exports, output, docstrings):71seen = {}72if output.options.keep_docstrings and docstrings and docstrings.length:73exports.push({'name': '__doc__', 'refname': 'ρσ_module_doc__'})74output.newline(), output.indent()75v = 'var'76output.assign(v + ' ρσ_module_doc__'), output.print(77JSON.stringify(create_doctring(docstrings)))78output.end_statement()79output.newline()80for symbol in exports:81if not Object.prototype.hasOwnProperty.call(seen, symbol.name):82output.indent()83if module_id.indexOf('.') is -1:84output.print('ρσ_modules.' + module_id + '.' + symbol.name)85else:86output.print('ρσ_modules["' + module_id + '"].' + symbol.name)87output.space(), output.print('='), output.space(), output.print(88symbol.refname or symbol.name)89seen[symbol.name] = True90output.end_statement()919293def prologue(module, output):94# any code that should appear before the main body95if output.options.omit_baselib:96return97output.indent()98v = 'var'99output.print(v), output.space()100output.spaced.apply(output, ((101'ρσ_iterator_symbol = (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") ? Symbol.iterator : "iterator-Symbol-5d0927e5554349048cf0e3762a228256"'102.split(' '))))103output.end_statement()104output.indent(), output.print(v), output.space()105output.spaced.apply(output, ((106'ρσ_kwargs_symbol = (typeof Symbol === "function") ? Symbol("kwargs-object") : "kwargs-object-Symbol-5d0927e5554349048cf0e3762a228256"'107.split(' '))))108output.end_statement()109output.indent(), output.spaced(110'var', 'ρσ_cond_temp,', 'ρσ_expr_temp,',111'ρσ_last_exception'), output.end_statement()112output.indent(), output.spaced('var', 'ρσ_object_counter', '=',113'0'), output.end_statement()114# Needed for Chrome < 51 and Edge as of August 2016115output.indent(), output.spaced(116'if(', 'typeof', 'HTMLCollection', '!==', '"undefined"', '&&',117'typeof', 'Symbol', '===', '"function")',118'NodeList.prototype[Symbol.iterator]', '=',119'HTMLCollection.prototype[Symbol.iterator]', '=',120'NamedNodeMap.prototype[Symbol.iterator]', '=',121'Array.prototype[Symbol.iterator]')122output.end_statement()123# output the baselib124if not output.options.baselib_plain:125raise ValueError(126'The baselib is missing! Remember to set the baselib_plain field on the options for OutputStream'127)128output.print(output.options.baselib_plain)129output.end_statement()130131132def print_top_level(self, output):133set_module_name(self.module_id)134is_main = self.module_id is '__main__'135136def write_docstrings():137if is_main and output.options.keep_docstrings and self.docstrings and self.docstrings.length:138output.newline(), output.indent()139v = 'var'140output.assign(v + ' ρσ_module_doc__'), output.print(141JSON.stringify(create_doctring(self.docstrings)))142output.end_statement()143144if output.options.private_scope and is_main:145146def f_main_function():147output.print("function()")148149def f_full_function():150# strict mode is more verbose about errors, and less forgiving about them151# kind of like Python152output.indent()153output.print('"use strict"')154output.end_statement()155156prologue(self, output)157write_imports(self, output)158output.newline()159output.indent()160161def f_function():162output.print("function()")163164def f_body():165write_main_name(output)166output.newline()167declare_vars(self.localvars, output)168display_body(self.body, True, output)169output.newline()170write_docstrings()171if self.comments_after and self.comments_after.length:172output.indent()173output_comments(self.comments_after, output)174output.newline()175176output.with_block(f_body)177178output.with_parens(f_function)179180output.print("();")181output.newline()182183output.with_block(f_full_function)184185output.with_parens(f_main_function)186output.print("();")187output.print("")188else:189if is_main:190prologue(self, output)191write_imports(self, output)192write_main_name(output)193194declare_vars(self.localvars, output)195display_body(self.body, True, output)196if self.comments_after and self.comments_after.length:197output_comments(self.comments_after, output)198set_module_name()199200201def print_module(self, output):202set_module_name(self.module_id)203204def output_module(output):205declare_vars(self.localvars, output)206display_body(self.body, True, output)207declare_exports(self.module_id, self.exports, output, self.docstrings)208209output.newline()210output.indent()211212def f_print_module():213output.print("function()")214215def dump_the_logic_of_this_module():216print_comments(self, output)217if output.options.write_name:218output.indent()219output.print('var ')220output.assign('__name__')221output.print('"' + self.module_id + '"')222output.semicolon()223output.newline()224225def output_key(beautify, keep_docstrings):226return 'beautify:' + beautify + ' keep_docstrings:' + keep_docstrings227228okey = output_key(output.options.beautify,229output.options.keep_docstrings)230if self.is_cached and okey in self.outputs:231output.print(self.outputs[okey])232else:233output_module(output)234if self.srchash and self.filename:235cached = {236'version': get_compiler_version(),237'signature': self.srchash,238'classes': {},239'baselib': self.baselib,240'nonlocalvars': self.nonlocalvars,241'imported_module_ids': self.imported_module_ids,242'exports': [],243'outputs': {},244'discard_asserts': bool(output.options.discard_asserts)245}246for cname in Object.keys(self.classes):247cobj = self.classes[cname]248cached.classes[cname] = {249'name': {250'name': cobj.name.name251},252'static': cobj.static,253'bound': cobj.bound,254'classvars': cobj.classvars255}256for symdef in self.exports:257cached.exports.push({'name': symdef.name})258for beautify in [True, False]:259for keep_docstrings in [True, False]:260co = OutputStream({261'beautify':262beautify,263'keep_docstrings':264keep_docstrings,265'write_name':266False,267'discard_asserts':268output.options.discard_asserts269})270co.with_indent(output.indentation(),271lambda: output_module(co))272raw = co.get()273cached.outputs[output_key(beautify,274keep_docstrings)] = raw275cached_name = cache_file_name(276self.filename, output.options.module_cache_dir)277try:278if cached_name:279writefile(cached_name,280JSON.stringify(cached, None, '\t'))281except Error as e:282console.error('Failed to write output cache file:',283cached_name, 'with error:', e)284285output.with_block(dump_the_logic_of_this_module)286287output.with_parens(f_print_module)288output.print("()")289output.semicolon()290output.newline()291set_module_name()292293294def print_imports(container, output):295is_first_aname = True296297def add_aname(aname, key, from_import):298nonlocal is_first_aname299if is_first_aname:300is_first_aname = False301else:302output.indent()303output.print('var ')304output.assign(aname)305if key.indexOf('.') is -1:306output.print('ρσ_modules.'), output.print(key)307else:308output.print('ρσ_modules["'), output.print(key), output.print('"]')309if from_import:310output.print('.')311output.print(from_import)312output.end_statement()313314for self in container.imports:315if self.argnames:316# A from import317for argname in self.argnames:318akey = argname.alias.name if argname.alias else argname.name319add_aname(akey, self.key, argname.name)320else:321if self.alias:322add_aname(self.alias.name, self.key, False)323else:324parts = self.key.split('.')325for i, part in enumerate(parts):326if i is 0:327add_aname(part, part, False)328else:329q = parts[:i + 1].join('.')330output.indent()331output.spaced(q, '=', 'ρσ_modules["' + q + '"]')332output.end_statement()333334335