From 46494869fdeb98a00dd3f8e1a54ed6070d9d807f Mon Sep 17 00:00:00 2001 From: zgy-ian Date: Tue, 11 Jan 2022 19:14:52 +0800 Subject: [PATCH] adapt ts Signed-off-by: zgy-ian --- test262/run_sunspider.py | 20 +- test262/run_test262.py | 38 +-- ts2panda/scripts/gen_diagnostic.sh | 22 -- ts2panda/scripts/gen_irnodes.sh | 30 -- ts2panda/scripts/generate_js_bytecode.py | 20 +- ts2panda/scripts/run.py | 4 +- ts2panda/scripts/run_tests.py | 68 ++-- ts2panda/src/base/util.ts | 35 +- ts2panda/src/cmdOptions.ts | 399 +++++++++++++---------- ts2panda/src/compiler.ts | 6 +- ts2panda/src/compilerDriver.ts | 209 +++++++----- ts2panda/src/debuginfo.ts | 2 +- ts2panda/src/index.ts | 208 ++++++------ ts2panda/src/pandagen.ts | 20 +- ts2panda/src/pandasm.ts | 17 +- ts2panda/src/statement/classStatement.ts | 13 +- ts2panda/src/ts2panda.ts | 83 +++-- ts2panda/tests/lexenv.test.ts | 15 +- ts2panda/tests/utils/base.ts | 3 +- ts2panda/ts2abc/ts2abc.cpp | 37 +-- 20 files changed, 700 insertions(+), 549 deletions(-) delete mode 100755 ts2panda/scripts/gen_diagnostic.sh delete mode 100755 ts2panda/scripts/gen_irnodes.sh diff --git a/test262/run_sunspider.py b/test262/run_sunspider.py index af5cdc6f94..87ee8da807 100755 --- a/test262/run_sunspider.py +++ b/test262/run_sunspider.py @@ -64,7 +64,7 @@ def parse_args(): ARK_ARGS = "--gc-type=epsilon" -ICU_PATH = f"--icu-data-path={CODE_ROOT}/third_party/icu/ohos_icu4j/data" +ICU_PATH = "--icu-data-path={}/third_party/icu/ohos_icu4j/data".format(CODE_ROOT) ARK_TOOL = DEFAULT_ARK_TOOL ARK_FRONTEND_TOOL = DEFAULT_ARK_FRONTEND_TOOL LIBS_DIR = DEFAULT_LIBS_DIR @@ -85,7 +85,7 @@ def output(retcode, msg): elif msg != '': sys.stderr.write(str(msg)) else: - sys.stderr.write("Unknown Error: " + str(retcode)) + sys.stderr.write("Unknown Error: {}".format(str(retcode))) def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT): @@ -109,8 +109,8 @@ def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT): if ret_code and ret_code != 1: code = ret_code - msg = f"Command {cmd_string}: \n" - msg += f"error: {str(errs.decode(code_format,'ignore'))}" + msg = "Command {}: \n".format(cmd_string) + msg += "error: {}".format(str(errs.decode(code_format,'ignore'))) else: code = 0 msg = str(msg.decode(code_format, 'ignore')) @@ -120,10 +120,10 @@ def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT): proc.terminate() os.kill(proc.pid, signal.SIGTERM) code = 1 - msg = f"Timeout:'{cmd_string}' timed out after' {str(timeout)} seconds" + msg = "Timeout:'{}' timed out after' {} seconds".format(cmd_string, str(timeout)) except Exception as err: code = 1 - msg = f"{cmd_string}: unknown error: {str(err)}" + msg = "{}: unknown error: {}".format(cmd_string, str(err)) output(code, msg) return code @@ -162,7 +162,7 @@ class ArkProgram(): js_file = self.js_file file_name_pre = os.path.splitext(js_file)[0] file_name = os.path.basename(js_file) - out_file = f"{file_name_pre}.abc" + out_file = "{}.abc".format(file_name_pre) mod_opt_index = 0 cmd_args = [] frontend_tool = self.ark_frontend_tool @@ -192,17 +192,17 @@ class ArkProgram(): qemu_arg2 = self.arch_root cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, ARK_ARGS, ICU_PATH, - f'{file_name_pre}.abc'] + "{}.abc".format(file_name_pre)] elif self.arch == ARK_ARCH_LIST[2]: qemu_tool = "qemu-arm" qemu_arg1 = "-L" qemu_arg2 = self.arch_root cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, ARK_ARGS, ICU_PATH, - f'{file_name_pre}.abc'] + "{}.abc".format(file_name_pre)] elif self.arch == ARK_ARCH_LIST[0]: cmd_args = [self.ark_tool, ARK_ARGS, ICU_PATH, - f'{file_name_pre}.abc'] + "{}.abc".format(file_name_pre)] retcode = exec_command(cmd_args) return retcode diff --git a/test262/run_test262.py b/test262/run_test262.py index 014c45062e..39de7a8791 100755 --- a/test262/run_test262.py +++ b/test262/run_test262.py @@ -138,7 +138,7 @@ def collect_files(path): return if not os.path.isdir(path): - raise ValueError(f'Not found: "{path}"') + raise ValueError("Not found: {}".format(path)) for root, _, file_names in os.walk(path): for file_name in file_names: @@ -151,7 +151,7 @@ def collect_files(path): def mkdstdir(file, src_dir, dist_dir): idx = file.rfind(src_dir) if idx == -1: - raise SystemExit(f'{file} can not found in {src_dir}') + raise SystemExit("{} can not found in {}".format(file, src_dir)) fpath, fname = os.path.split(file[idx:]) fpath = fpath.replace(src_dir, dist_dir) @@ -245,7 +245,7 @@ class TestPrepare(): dstdir = os.path.join(TEST_ES2015_DIR, file) elif self.args.ci_build: dstdir = os.path.join(TEST_CI_DIR, file) - subprocess.getstatusoutput("cp %s %s" % (srcdir, dstdir)) + subprocess.getstatusoutput("cp {} {}".format(srcdir, dstdir)) def collect_tests(self): files = [] @@ -413,15 +413,15 @@ def get_host_args(args, host_type): ark_frontend = args.ark_frontend if host_type == DEFAULT_HOST_TYPE: - host_args = f"-B test262/run_sunspider.py " - host_args += f"--ark-tool={ark_tool} " - host_args += f"--ark-frontend-tool={ark_frontend_tool} " - host_args += f"--libs-dir={libs_dir} " - host_args += f"--ark-frontend={ark_frontend} " + host_args = "-B test262/run_sunspider.py " + host_args += "--ark-tool={} ".format(ark_tool) + host_args += "--ark-frontend-tool={} ".format(ark_frontend_tool) + host_args += "--libs-dir={} ".format(libs_dir) + host_args += "--ark-frontend={} ".format(ark_frontend) if args.ark_arch != ark_arch: - host_args += f"--ark-arch={args.ark_arch} " - host_args += f"--ark-arch-root={args.ark_arch_root} " + host_args += "--ark-arch={} ".format(args.ark_arch) + host_args += "--ark-arch-root={} ".format(args.ark_arch_root) return host_args @@ -434,15 +434,15 @@ def run_test262_test(args): timeout = get_timeout(args, threads) test_cmd = ["node", TEST262_RUNNER_SCRIPT] - test_cmd.append(f"--hostType={host_type}") - test_cmd.append(f"--hostPath={host_path}") + test_cmd.append("--hostType={}".format(host_type)) + test_cmd.append("--hostPath={}".format(host_path)) if host_args != "": - test_cmd.append(f"--hostArgs='{host_args}'") - test_cmd.append(f"--threads={threads}") - test_cmd.append(f"--mode={run_test262_mode(args)}") - test_cmd.append(f"--timeout={timeout}") - test_cmd.append(f"--tempDir={BASE_OUT_DIR}") - test_cmd.append(f"--test262Dir={DATA_DIR}") + test_cmd.append("--hostArgs='{}'".format(host_args)) + test_cmd.append("--threads={}".format(threads)) + test_cmd.append("--mode={}".format(run_test262_mode(args))) + test_cmd.append("--timeout={}".format(timeout)) + test_cmd.append("--tempDir={}".format(BASE_OUT_DIR)) + test_cmd.append("--test262Dir={}".format(DATA_DIR)) if args.babel: test_cmd.append("--preprocessor='test262/babel-preprocessor.js'") @@ -465,7 +465,7 @@ def main(args): if ret: sys.exit(ret) endtime = datetime.datetime.now() - print(f"used time is: {str(endtime - starttime)}") + print("used time is: {}".format(str(endtime - starttime))) if __name__ == "__main__": diff --git a/ts2panda/scripts/gen_diagnostic.sh b/ts2panda/scripts/gen_diagnostic.sh deleted file mode 100755 index 3f5e53eb61..0000000000 --- a/ts2panda/scripts/gen_diagnostic.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -PANDA_ROOT="../submodules/panda" -ISA="scripts/diagnosticMessages.json" -TEMPLATE="templates/diagnostic.ts.erb" -OUTPUT="src/diagnostic.ts" - -ruby scripts/gen_diagnostic.rb --template $TEMPLATE --data $ISA --output $OUTPUT diff --git a/ts2panda/scripts/gen_irnodes.sh b/ts2panda/scripts/gen_irnodes.sh deleted file mode 100755 index e3ba64b5af..0000000000 --- a/ts2panda/scripts/gen_irnodes.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -PANDA_ROOT="../submodules/panda" -ISA="$PANDA_ROOT/isa/isa.yaml" -DEPS="$PANDA_ROOT/isa/isapi.rb,$PANDA_ROOT/libpandafile/pandafile_isapi.rb" -TEMPLATE="templates/irnodes.ts.erb" -OUTPUT="src/irnodes.ts" - -ruby $PANDA_ROOT/isa/gen.rb --template $TEMPLATE --data $ISA --output $OUTPUT --require "$DEPS" - -BUILTIN_DATA="$PANDA_ROOT/isa/builtins.yaml" -BUILTIN_REQS="$PANDA_ROOT/isa/builtinsapi.rb,$PANDA_ROOT/runtime/ecmascript/ecma_builtins.rb" -BUILTIN_TEMPLATE="templates/builtinsMap.ts.erb" -BUILTIN_OUTPUT="src/builtinsMap.ts" - -ruby $PANDA_ROOT/isa/gen.rb --template $BUILTIN_TEMPLATE --data $BUILTIN_DATA --output $BUILTIN_OUTPUT --require "$BUILTIN_REQS" diff --git a/ts2panda/scripts/generate_js_bytecode.py b/ts2panda/scripts/generate_js_bytecode.py index 755b07a6da..62c1c64b7d 100755 --- a/ts2panda/scripts/generate_js_bytecode.py +++ b/ts2panda/scripts/generate_js_bytecode.py @@ -19,6 +19,7 @@ Description: Generate javascript byte code """ import os +import string import subprocess import platform import argparse @@ -40,6 +41,12 @@ def parse_args(): help='whether add debuginfo') parser.add_argument("--module", action='store_true', help='whether is module') + parser.add_argument("--dts-type-record", action='store_true', + help='Record type info for .d.ts files. Default: false') + parser.add_argument("--merge-abc-files", action='store_true', + help='Merge multiple abc files into one. Default: false') + parser.add_argument("--other-files", nargs='*', + help='other files') arguments = parser.parse_args() return arguments @@ -53,7 +60,7 @@ def set_env(input_arguments): def run_command(cmd, execution_path): - print(" ".join(cmd) + " | execution_path: " + execution_path) + print("{} | execution_path:{}".format(" ".join(cmd), execution_path)) proc = subprocess.Popen(cmd, cwd=execution_path) proc.wait() @@ -77,13 +84,20 @@ def gen_abc_info(input_arguments): '--expose-gc', os.path.join(name, 'src/index.js'), input_arguments.src_js, - '-o', input_arguments.dst_file, - '-t', '0'] + '-o', + input_arguments.dst_file] if input_arguments.debug: cmd.insert(3, '--debug') if input_arguments.module: cmd.insert(4, '-m') + if input_arguments.dts_type_record: + cmd.append('--dts-type-record') + if input_arguments.merge_abc_files: + cmd.append('--merge-abc-files') + if input_arguments.other_files: + cmd.append(input_arguments.other_files) + run_command(cmd, path) diff --git a/ts2panda/scripts/run.py b/ts2panda/scripts/run.py index 089868e28e..2cc4c1568f 100755 --- a/ts2panda/scripts/run.py +++ b/ts2panda/scripts/run.py @@ -51,10 +51,10 @@ def set_env(node_dir): def run_command(cmd, execution_path=os.getcwd()): - print(" ".join(cmd) + " | execution_path: " + execution_path) + print("{} | execution_path:{}".format(" ".join(cmd), execution_path)) proc = subprocess.Popen(cmd, cwd=execution_path) ret = proc.wait() - assert not ret, f'\n{" ".join(cmd)} failed' + assert not ret, "\n{} failed".format(" ".join(cmd)) def node_modules(options): diff --git a/ts2panda/scripts/run_tests.py b/ts2panda/scripts/run_tests.py index 5289947436..d712fc0392 100755 --- a/ts2panda/scripts/run_tests.py +++ b/ts2panda/scripts/run_tests.py @@ -35,21 +35,21 @@ DEFAULT_NODE_MODULE = os.path.join( def parse_args(): parser = argparse.ArgumentParser() - parser.add_argument('--src-dir', + parser.add_argument("--src-dir", default=TS2PANDA_DIR, - help='Source directory') - parser.add_argument('--dist-dir', + help="Source directory") + parser.add_argument("--dist-dir", default=DEFAULT_TARGET_DIR, - help='Destination directory') + help="Destination directory") parser.add_argument("--node-modules", default=DEFAULT_NODE_MODULE, - help='path to node-modules exetuable') - parser.add_argument('--platform', + help="path to node-modules exetuable") + parser.add_argument("--platform", default="linux", - help='platform, as: linux, mac, win') - parser.add_argument('--js-file', - metavar='FILE', - help='The name of the test use case file to execute') + help="platform, as: linux, mac, win") + parser.add_argument("--js-file", + metavar="FILE", + help="The name of the test use case file to execute") return parser.parse_args() @@ -85,37 +85,38 @@ class Ts2abcTests(): def copy_node_modules(self): src_dir = self.src_dir dist_dir = self.dist_dir - run_command(['cp', '-f', os.path.join(src_dir, "package.json"), + run_command(["cp", "-f", os.path.join(src_dir, "package.json"), os.path.join(dist_dir, "package.json")]) - run_command(['cp', '-f', os.path.join(src_dir, "package-lock.json"), + run_command(["cp", "-f", os.path.join(src_dir, "package-lock.json"), os.path.join(dist_dir, "package-lock.json")]) if self.node_modules: - run_command(['cp', '-rf', self.node_modules, dist_dir]) + run_command(["cp", "-rf", self.node_modules, dist_dir]) else: - run_command(['npm', 'install'], dist_dir) + run_command(["npm", "install"], dist_dir) def copy_tests(self): - if os.path.exists(f'{self.dist_dir}/tests'): - run_command(['rm', '-rf', f'{self.dist_dir}/tests']) - run_command(['cp', '-rf', f'{self.src_dir}/tests', self.dist_dir]) + if os.path.exists("{}/tests".format(self.dist_dir)): + run_command(["rm", "-rf", "{}/tests".format(self.dist_dir)]) + run_command( + ["cp", "-rf", "{}/tests".format(self.src_dir), self.dist_dir]) def run_build(self): plat_form = self.platform tsc = "node_modules/typescript/bin/tsc" if plat_form == "linux": - cmd = [tsc, '-b', 'src', 'tests'] + cmd = [tsc, "-b", "src", "tests"] ret = run_command(cmd, self.dist_dir) elif plat_form == "win": - cmd = [tsc, '-b', 'src/tsconfig.win.json', - 'tests/tsconfig.win.json'] + cmd = [tsc, "-b", "src/tsconfig.win.json", + "tests/tsconfig.win.json"] ret = run_command(cmd, self.dist_dir) - elif plat_form == 'mac': - cmd = [tsc, '-b', 'src/tsconfig.mac.json', - 'tests/tsconfig.mac.json'] + elif plat_form == "mac": + cmd = [tsc, "-b", "src/tsconfig.mac.json", + "tests/tsconfig.mac.json"] ret = run_command(cmd, self.dist_dir) if ret: - raise RuntimeError("Run [" + " ".join(cmd) + "] failed !") + raise RuntimeError("Run [ {} ] failed !".format(" ".join(cmd))) def run_tests(self): os.chdir(self.dist_dir) @@ -129,19 +130,18 @@ class Ts2abcTests(): tests_args = "tests/**/*.test.js" if plat_form == "linux": - cmd = [mocha, f'build/{tests_args}'] - ret = run_command(cmd, self.dist_dir) + cmd = [mocha, "build/{}".format(tests_args)] elif plat_form == "win": - cmd = [mocha, f'build-win/{tests_args}'] - ret = run_command(cmd, self.dist_dir) - elif plat_form == 'mac': - cmd = [mocha, f'build-mac/{tests_args}'] - ret = run_command(cmd, self.dist_dir) + cmd = [mocha, "build-win/{}".format(tests_args)] + elif plat_form == "mac": + cmd = [mocha, "build-mac/{}".format(tests_args)] + cmd.extend(["--exit", "--recursive", "--timeout", "30000000"]) + ret = run_command(cmd, self.dist_dir) if ret: - raise RuntimeError("Run [" + " ".join(cmd) + "] failed !") + raise RuntimeError("Run [ {} ] failed !".format(" ".join(cmd))) else: - print("Run [" + " ".join(cmd) + "] success!") - print("used: %.5f seconds" % (time.time() - start_time)) + print("Run [ {} ] success!".format(" ".join(cmd))) + print("used: {:0,.5f} seconds".format(time.time() - start_time)) def main(): diff --git a/ts2panda/src/base/util.ts b/ts2panda/src/base/util.ts index e0f66130a0..bc40beb0ab 100755 --- a/ts2panda/src/base/util.ts +++ b/ts2panda/src/base/util.ts @@ -28,6 +28,7 @@ import * as jshelpers from "../jshelpers"; import { LOGD } from "../log"; import { ModuleScope, Scope } from "../scope"; import { isFunctionLikeDeclaration } from "../syntaxCheckHelper"; +import { CmdOptions } from "../cmdOptions"; export function containSpreadElement(args?: ts.NodeArray): boolean { if (!args) { @@ -196,7 +197,7 @@ export function initiateTs2abc(args: Array) { args.unshift("--compile-by-pipe"); var spawn = require('child_process').spawn; let child = spawn(js2abc, [...args], { - stdio: ['pipe', 'inherit', 'inherit', 'pipe'] + stdio: ['pipe', 'inherit', 'pipe', 'pipe'] }); return child; @@ -206,10 +207,19 @@ export function terminateWritePipe(ts2abc: any) { if (!ts2abc) { LOGD("ts2abc is not a valid object"); } - ts2abc.stdio[3].end(); } +export function initiateTs2abcChildProcess(outputFileName: string): any { + let ts2abcProcess; + if (!CmdOptions.isAssemblyMode()) { + ts2abcProcess = initiateTs2abc([outputFileName]); + listenChildExit(ts2abcProcess); + listenErrorEvent(ts2abcProcess); + } + return ts2abcProcess; +} + export function listenChildExit(child: any) { if (!child) { LOGD("child is not a valid object"); @@ -295,4 +305,25 @@ export function getRangeStartVregPos(ins: IRNode): number { return -1; } return ins instanceof EcmaCreateobjectwithexcludedkeys ? 2 : 1; +} + +export function checkIsGlobalDeclaration(sourceFile: ts.SourceFile) { + for (let statement of sourceFile.statements) { + if (statement.modifiers) { + for (let modifier of statement.modifiers) { + if (modifier.kind === ts.SyntaxKind.ExportKeyword) { + return false; + } + } + } else if (statement.kind === ts.SyntaxKind.ExportAssignment) { + return false; + } else if (statement.kind === ts.SyntaxKind.ImportKeyword || statement.kind === ts.SyntaxKind.ImportDeclaration) { + return false; + } + } + return true; +} + +export function isSourceFileFromLibrary(program:ts.Program, node: ts.SourceFile) { + return program.isSourceFileFromExternalLibrary(node) || program.isSourceFileDefaultLibrary(node); } \ No newline at end of file diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 884d706ea7..6bd289f5e9 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -22,214 +22,281 @@ import path = require("path"); import { execute } from "./base/util"; const ts2pandaOptions = [ - { name: 'variant-bytecode', alias: 'r', type: Boolean, defaultValue: true, description: "emit 2nd bytecode to pandafile." }, - { name: 'modules', alias: 'm', type: Boolean, defaultValue: false, description: "compile as module." }, - { name: 'debug-log', alias: 'l', type: Boolean, defaultValue: false, description: "show info debug log and generate the json file."}, - { name: 'dump-assembly', alias: 'a', type: Boolean, defaultValue: false, description: "dump assembly to file." }, - { name: 'debug', alias: 'd', type: Boolean, defaultValue: false, description: "compile with debug info." }, - { name: 'show-statistics', alias: 's', type: String, lazyMultiple: true, defaultValue: "", description: "show compile statistics(ast, histogram, hoisting, all)." }, - { name: 'output', alias: 'o', type: String, defaultValue: "", description: "set output file." }, - { name: 'timeout', alias: 't', type: Number, defaultValue: 0, description: "js to abc timeout threshold(unit: seconds)." }, - { name: 'opt-log-level', type: String, defaultValue: "error", description: "specifie optimizer log level. Possible values: ['debug', 'info', 'error', 'fatal']" }, - { - name: 'opt-level', type: Number, defaultValue: 1, description: "Optimization level. Possible values: [0, 1, 2]. Default: 0\n 0: no optimizations\n \ - 1: basic bytecode optimizations, including valueNumber, lowering, constantResolver, regAccAllocator\n \ - 2: other bytecode optimizations, unimplemented yet"}, - { name: 'help', alias: 'h', type: Boolean, description: "Show usage guide." }, - { name: 'bc-version', alias: 'v', type: Boolean, defaultValue: false, description: "Print ark bytecode version" }, - { name: 'bc-min-version', type: Boolean, defaultValue: false, description: "Print ark bytecode minimum supported version" }, - { name: 'included-files', alias: 'i', type: String, lazyMultiple: true, defaultValue: [], description: "The list of dependent files." }, - { name: 'record-type', alias: 'p', type: Boolean, defaultValue: false, description: "Record type info. Default: true" }, - { name: 'dts-type-record', alias: 'q', type: Boolean, defaultValue: false, description: "Record type info for .d.ts files. Default: false" }, - { name: 'debug-type', alias: 'g', type: Boolean, defaultValue: false, description: "Print type-related log. Default: false" }, - { name: 'output-type', type: Boolean, defaultValue: false, description: "set output type."} + { + name: 'variant-bytecode', alias: 'r', type: Boolean, defaultValue: true, + description: "emit 2nd bytecode to pandafile." + }, + { + name: 'modules', alias: 'm', type: Boolean, defaultValue: false, + description: "compile as module." + }, + { + name: 'debug-log', alias: 'l', type: Boolean, defaultValue: false, + description: "show info debug log." + }, + { + name: 'dump-assembly', alias: 'a', type: Boolean, defaultValue: false, + description: "dump assembly to file." + }, + { + name: 'debug', alias: 'd', type: Boolean, defaultValue: false, + description: "compile with debug info." + }, + { + name: 'show-statistics', alias: 's', type: String, lazyMultiple: true, defaultValue: "", + description: "show compile statistics(ast, histogram, hoisting, all)." + }, + { + name: 'output', alias: 'o', type: String, defaultValue: "", + description: "set output file." + }, + { + name: 'timeout', alias: 't', type: Number, defaultValue: 0, + description: "js to abc timeout threshold(unit: seconds)." + }, + { + name: 'opt-log-level', type: String, defaultValue: "error", + description: "specifie optimizer log level. Possible values: ['debug', 'info', 'error', 'fatal']" + }, + { + name: 'opt-level', type: Number, defaultValue: 1, + description: `Optimization level. Possible values: [0, 1, 2]. Default: 0\n + 0: no optimizations\n + 1: basic bytecode optimizations, including valueNumber, lowering, constantResolver, regAccAllocator\n + 2: other bytecode optimizations, unimplemented yet` + }, + { + name: 'help', alias: 'h', type: Boolean, + description: "Show usage guide." + }, + { + name: 'bc-version', alias: 'v', type: Boolean, defaultValue: false, + description: "Print ark bytecode version" + }, + { + name: 'bc-min-version', type: Boolean, defaultValue: false, + description: "Print ark bytecode minimum supported version" + }, + { + name: 'record-type', alias: 'p', type: Boolean, defaultValue: false, + description: "Record type info. Default: true" + }, + { + name: 'dts-type-record', alias: 'q', type: Boolean, defaultValue: false, + description: "Record type info for .d.ts files. Default: false" + }, + { + name: 'debug-type', alias: 'g', type: Boolean, defaultValue: false, + description: "Record type info for .d.ts files. Default: false" + }, + { + name: 'output-type', type: Boolean, defaultValue: false, + description: "set output type." + }, + { + name: 'merge-abc-files', alias: 'e', type: Boolean, defaultValue: false, + description: "Merge multiple abc files into one" + }, + { + name: 'modules-dir-map', type: String, defaultValue: "", + description: "The modules path map relation table." + } ] - - export class CmdOptions { - private static parsedResult: ts.ParsedCommandLine; - private static options: commandLineArgs.CommandLineOptions; + private static parsedResult: ts.ParsedCommandLine; + private static options: commandLineArgs.CommandLineOptions; - static isEnableDebugLog(): boolean { - if (!this.options) { - return false; - } - return this.options["debug-log"]; + static isEnableDebugLog(): boolean { + if (!this.options) { + return false; } + return this.options["debug-log"]; + } - static isAssemblyMode(): boolean { - if (!this.options) { - return false; - } - return this.options["dump-assembly"]; + static isAssemblyMode(): boolean { + if (!this.options) { + return false; } + return this.options["dump-assembly"]; + } - static isDebugMode(): boolean { - if (!this.options) { - return false; - } - return this.options["debug"]; + static isDebugMode(): boolean { + if (!this.options) { + return false; } + return this.options["debug"]; + } - static isModules(): boolean { - if (!this.options) { - return false; - } - return this.options["modules"]; + static isModules(): boolean { + if (!this.options) { + return false; } + return this.options["modules"]; + } - static isVariantBytecode(): boolean { - if (!this.options) { - return true; - } - return this.options["variant-bytecode"]; + static isVariantBytecode(): boolean { + if (!this.options) { + return true; } + return this.options["variant-bytecode"]; + } - static getOptLevel(): number { - return this.options["opt-level"]; - } + static getOptLevel(): number { + return this.options["opt-level"]; + } - static getOptLogLevel(): string { - return this.options["opt-log-level"]; - } + static getOptLogLevel(): string { + return this.options["opt-log-level"]; + } - static showASTStatistics(): boolean { - if (!this.options) { - return false; - } - return this.options["show-statistics"].includes("ast") || this.options["show-statistics"].includes("all"); + static showASTStatistics(): boolean { + if (!this.options) { + return false; } + return this.options["show-statistics"].includes("ast") || this.options["show-statistics"].includes("all"); + } - static showHistogramStatistics(): boolean { - if (!this.options) { - return false; - } - return this.options["show-statistics"].includes("all") || this.options["show-statistics"].includes("histogram"); + static showHistogramStatistics(): boolean { + if (!this.options) { + return false; } + return this.options["show-statistics"].includes("all") || this.options["show-statistics"].includes("histogram"); + } - static showHoistingStatistics(): boolean { - if (!this.options) { - return false; - } - return this.options["show-statistics"].includes("all") || this.options["show-statistics"].includes("hoisting"); + static showHoistingStatistics(): boolean { + if (!this.options) { + return false; } - - static getInputFileName(): string { - let path = this.parsedResult.fileNames[0]; - let inputFile = path.substring(0, path.lastIndexOf('.')); - return inputFile; + return this.options["show-statistics"].includes("all") || this.options["show-statistics"].includes("hoisting"); + } + + static getInputFileName(): string { + let path = this.parsedResult.fileNames[0]; + let inputFile = path.substring(0, path.lastIndexOf('.')); + return inputFile; + } + + static getOutputFileName(): string { + let outputFile = this.options.output; + if (outputFile == "") { + outputFile = CmdOptions.getInputFileName() + ".abc"; } + return outputFile; + } - static getOutputBinName(): string { - let outputFile = this.options.output; - if (outputFile == "") { - outputFile = CmdOptions.getInputFileName() + ".abc"; - } - return outputFile; + static getTimeOut(): Number { + if (!this.options) { + return 0; } + return this.options["timeout"]; + } - static getTimeOut(): Number { - if (!this.options) { - return 0; - } - return this.options["timeout"]; + static isOutputType(): false { + if (!this.options) { + return false; } - - static isOutputType(): false { - if (!this.options) { - return false; - } - return this.options["output-type"]; + return this.options["output-type"]; + } + + static showHelp(): void { + const usage = commandLineUsage([ + { + header: "Ark JavaScript Compiler", + content: 'node --expose-gc index.js [options] file.js' + }, + { + header: 'Options', + optionList: ts2pandaOptions + }, + { + content: 'Project Ark' + } + ]) + LOGE(usage); + } + + static isBcVersion(): boolean { + if (!this.options) { + return false; } - - static showHelp(): void { - const usage = commandLineUsage([ - { - header: "Ark JavaScript Compiler", - content: 'node --expose-gc index.js [options] file.js' - }, - { - header: 'Options', - optionList: ts2pandaOptions - }, - { - content: 'Project Ark' - } - ]) - LOGE(usage); + return this.options["bc-version"]; + } + + static getVersion(isBcVersion: boolean = true): void { + let js2abc = path.join(path.resolve(__dirname, '../bin'), "js2abc"); + let version_arg = isBcVersion ? "--bc-version" : "--bc-min-version" + execute(`${js2abc}`, [version_arg]); + } + + static isBcMinVersion(): boolean { + if (!this.options) { + return false; } + return this.options["bc-min-version"]; + } - static isBcVersion(): boolean { - if (!this.options) { - return false; - } - return this.options["bc-version"]; + static needRecordType(): boolean { + if (!this.options) { + return false; } - static getVersion(isBcVersion: boolean = true): void { - let js2abc = path.join(path.resolve(__dirname, '../bin'), "js2abc"); - let version_arg = isBcVersion ? "--bc-version" : "--bc-min-version" - execute(`${js2abc}`, [version_arg]); - } + return !this.options["record-type"]; + } - static isBcMinVersion(): boolean { - if (!this.options) { - return false; - } - return this.options["bc-min-version"]; + static needRecordDtsType(): boolean { + if (!this.options) { + return false; } + return this.options["dts-type-record"]; + } - static getIncludedFiles(): string[] { - if (!this.options) { - return []; - } - - return this.options["included-files"]; + static enableTypeLog(): boolean { + if (!this.options) { + return false; } + return this.options["debug-type"]; + } - static needRecordType(): boolean { - if (!this.options) { - return false; - } - - return !this.options["record-type"]; + static getModulesDirMap(): string[] { + if (!this.options) { + return []; } - - static needRecordDtsType(): boolean { - if (!this.options) { - return false; - } - return this.options["dts-type-record"]; + let file = this.options["modules-dir-map"]; + if (file) { + let files = file.split(","); + return files; } + return []; + } - static enableTypeLog(): boolean { - if (!this.options) { - return false; - } - return this.options["debug-type"]; + static isMergeAbcFiles(): boolean { + if (!this.options) { + return false; + } + return this.options["merge-abc-files"]; + } + + static parseUserCmd(args: string[]): ts.ParsedCommandLine | undefined { + this.options = commandLineArgs(ts2pandaOptions, { partial: true }); + if (this.options.help) { + this.showHelp(); + return undefined; } - static parseUserCmd(args: string[]): ts.ParsedCommandLine | undefined { - this.options = commandLineArgs(ts2pandaOptions, { partial: true }); - if (this.options.help) { - this.showHelp(); - return undefined; - } - - if (this.isBcVersion() || this.isBcMinVersion()) { - this.getVersion(this.isBcVersion()); - return undefined; - } - - if (!this.options._unknown) { - LOGE("options at least one file is needed"); - this.showHelp(); - return undefined; - } + if (this.isBcVersion() || this.isBcMinVersion()) { + this.getVersion(this.isBcVersion()); + return undefined; + } - this.parsedResult = ts.parseCommandLine(this.options._unknown!); - return this.parsedResult; + if (!this.options._unknown) { + LOGE("options at least one file is needed"); + this.showHelp(); + return undefined; } + this.parsedResult = ts.parseCommandLine(this.options._unknown!); + return this.parsedResult; + } + } diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index b323fc7b57..522305dc5d 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -498,6 +498,9 @@ export class Compiler { case ts.SyntaxKind.ExportDeclaration: case ts.SyntaxKind.NotEmittedStatement: case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ModuleDeclaration: break; default: throw new Error("Statement " + this.getNodeName(stmt) + " is unimplemented"); @@ -772,7 +775,7 @@ export class Compiler { compileExpression(expr: ts.Expression) { // Please keep order of cases the same as in types.ts - LOGD(this.debugTag, "compile expr:" + expr.kind); + LOGD(this.debugTag, "compile expr:" + this.getNodeName(expr)); switch (expr.kind) { case ts.SyntaxKind.NumericLiteral: // line 34 compileNumericLiteral(this.pandaGen, expr); @@ -872,6 +875,7 @@ export class Compiler { compileClassDeclaration(this, expr); break; case ts.SyntaxKind.PartiallyEmittedExpression: + case ts.SyntaxKind.AsExpression: break; default: throw new Error("Expression of type " + this.getNodeName(expr) + " is unimplemented"); diff --git a/ts2panda/src/compilerDriver.ts b/ts2panda/src/compilerDriver.ts index e4dd5dc0c6..9a247cdddb 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -17,11 +17,13 @@ import { writeFileSync } from "fs"; import * as ts from "typescript"; import { addVariableToScope } from "./addVariable2Scope"; import { AssemblyDumper } from "./assemblyDumper"; -import { initiateTs2abc, listenChildExit, listenErrorEvent, terminateWritePipe } from "./base/util"; -import { CmdOptions } from "./cmdOptions"; +import { LiteralBuffer } from "./base/literal"; import { - Compiler -} from "./compiler"; + initiateTs2abcChildProcess, + terminateWritePipe +} from "./base/util"; +import { CmdOptions } from "./cmdOptions"; +import { Compiler } from "./compiler"; import { CompilerStatistics } from "./compilerStatistics"; import { DebugInfo } from "./debuginfo"; import { hoisting } from "./hoisting"; @@ -44,7 +46,6 @@ import { getClassNameForConstructor } from "./statement/classStatement"; import { checkDuplicateDeclaration, checkExportEntries } from "./syntaxChecker"; import { Ts2Panda } from "./ts2panda"; import { TypeRecorder } from "./typeRecorder"; -import { LiteralBuffer } from "./base/literal"; export class PendingCompilationUnit { constructor( @@ -59,7 +60,7 @@ export class PendingCompilationUnit { * It handles all dependencies and run passes. */ export class CompilerDriver { - private fileName: string; + private outputfileName: string; private passes: Pass[]; private compilationUnits: PandaGen[]; pendingCompilationUnits: PendingCompilationUnit[]; @@ -68,31 +69,34 @@ export class CompilerDriver { private statistics: CompilerStatistics; private needDumpHeader: boolean = true; private ts2abcProcess: any = undefined; + private recoderName: string; - constructor(fileName: string) { - this.fileName = fileName; + constructor(outputFileName: string, ts2abcProc: any, recoderName: string) { + this.outputfileName = outputFileName; // register passes here this.passes = [ new CacheExpander(), new IntrinsicExpander(), - new RegAlloc() + new RegAlloc(), ]; this.compilationUnits = []; this.pendingCompilationUnits = []; this.statistics = new CompilerStatistics(); - } - - initiateTs2abcChildProcess() { - this.ts2abcProcess = initiateTs2abc([this.fileName]); + this.ts2abcProcess = ts2abcProc; + this.recoderName = recoderName; } getTs2abcProcess(): any { if (this.ts2abcProcess === undefined) { - throw new Error("ts2abc hasn't been initiated") + throw new Error("ts2abc hasn't been initiated"); } return this.ts2abcProcess; } + setTs2abcProcess(ts2abcProc: any) { + this.ts2abcProcess = ts2abcProc; + } + getStatistics() { return this.statistics; } @@ -101,7 +105,15 @@ export class CompilerDriver { this.passes = passes; } - addCompilationUnit(decl: ts.FunctionLikeDeclaration, scope: Scope, recorder: Recorder): string { + getRecoderName(): string { + return this.recoderName; + } + + addCompilationUnit( + decl: ts.FunctionLikeDeclaration, + scope: Scope, + recorder: Recorder + ): string { let internalName = this.getFuncInternalName(decl, recorder); this.pendingCompilationUnits.push( new PendingCompilationUnit(decl, scope, internalName) @@ -118,10 +130,10 @@ export class CompilerDriver { } getASTStatistics(node: ts.Node, statics: number[]) { - node.forEachChild(childNode => { + node.forEachChild((childNode) => { statics[childNode.kind] = statics[childNode.kind] + 1; this.getASTStatistics(childNode, statics); - }) + }); } // sort all function in post order @@ -146,71 +158,82 @@ export class CompilerDriver { } compileForSyntaxCheck(node: ts.SourceFile): void { - let recorder = this.compilePrologue(node, false); - checkDuplicateDeclaration(recorder); - checkExportEntries(recorder); + try { + let recorder = this.compilePrologue(node, false); + checkDuplicateDeclaration(recorder); + checkExportEntries(recorder); + } catch (err) { + if (CmdOptions.isMergeAbcFiles()) { + terminateWritePipe(this.getTs2abcProcess()); + } + throw err; + } } compile(node: ts.SourceFile): void { - if (CmdOptions.showASTStatistics()) { - let statics: number[] = new Array(ts.SyntaxKind.Count).fill(0); - - this.getASTStatistics(node, statics); - statics.forEach((element, idx) => { - if (element > 0) { - LOGD(this.kind2String(idx) + " = " + element); - } - }); + this.showASTStatistics(node); + if (!CmdOptions.isMergeAbcFiles()) { + let ts2abcProc: any = initiateTs2abcChildProcess(this.outputfileName); + this.setTs2abcProcess(ts2abcProc); } - let recorder = this.compilePrologue(node, true); + let recorder: Recorder; + try { + recorder = this.compilePrologue(node, true); + } catch (err) { + terminateWritePipe(this.getTs2abcProcess()); + throw err; + } - // initiate ts2abc if (!CmdOptions.isAssemblyMode()) { - this.initiateTs2abcChildProcess(); - let ts2abcProc = this.getTs2abcProcess(); - listenChildExit(ts2abcProc); - listenErrorEvent(ts2abcProc); - try { - Ts2Panda.dumpCmdOptions(ts2abcProc); - - for (let i = 0; i < this.pendingCompilationUnits.length; i++) { - let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); - } - - Ts2Panda.dumpStringsArray(ts2abcProc); - Ts2Panda.dumpConstantPool(ts2abcProc); + this.prePendingCompilationUnits(recorder); - terminateWritePipe(ts2abcProc); - if (CmdOptions.isEnableDebugLog()) { - let jsonFileName = this.fileName.substring(0, this.fileName.lastIndexOf(".")).concat(".json"); - writeFileSync(jsonFileName, Ts2Panda.jsonString); - LOGD("Successfully generate ", `${jsonFileName}`); + if (!CmdOptions.isMergeAbcFiles()) { + Ts2Panda.dumpCommonFields(this.getTs2abcProcess(), this.outputfileName); + Ts2Panda.clearDumpData(); } if (CmdOptions.isOutputType()) { - let typeFileName = this.fileName.substring(0, this.fileName.lastIndexOf(".")).concat(".txt"); + let typeFileName = this.outputfileName.substring(0, this.outputfileName.lastIndexOf(".")).concat(".txt"); writeFileSync(typeFileName, Ts2Panda.dumpTypeLiteralArrayBuffer()); } - Ts2Panda.clearDumpData(); + // Ts2Panda.clearDumpData(); } catch (err) { - terminateWritePipe(ts2abcProc); + terminateWritePipe(this.getTs2abcProcess()); throw err; } } else { - for (let i = 0; i < this.pendingCompilationUnits.length; i++) { - let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); - } + this.prePendingCompilationUnits(recorder); } - PandaGen.clearLiteralArrayBuffer(); + if (!CmdOptions.isMergeAbcFiles()) { + PandaGen.clearRecoders(); + PandaGen.clearLiteralArrayBuffer(); + } } - private compileImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, - internalName: string, recorder: Recorder): void { + private showASTStatistics(node: ts.SourceFile): void { + if (CmdOptions.showASTStatistics()) { + let statics: number[] = new Array(ts.SyntaxKind.Count).fill(0); + + this.getASTStatistics(node, statics); + statics.forEach((element, idx) => { + if (element > 0) { + LOGD(this.kind2String(idx) + " = " + element); + } + }); + } + } + + private prePendingCompilationUnits(recorder: Recorder): void { + for (let i = 0; i < this.pendingCompilationUnits.length; i++) { + let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; + this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); + } + } + + private compileImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder): void { let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); // for debug info DebugInfo.addDebugIns(scope, pandaGen, true); @@ -249,7 +272,12 @@ export class CompilerDriver { for (let i = 0; i < this.pendingCompilationUnits.length; i++) { let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileUnitTestImpl(unit.decl, unit.scope, unit.internalName, recorder); + this.compileUnitTestImpl( + unit.decl, + unit.scope, + unit.internalName, + recorder + ); } if (literalBufferArray) { PandaGen.getLiteralArrayBuffer().forEach(val => literalBufferArray.push(val)); @@ -258,12 +286,15 @@ export class CompilerDriver { PandaGen.clearLiteralArrayBuffer(); } - private compileUnitTestImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, - internalName: string, recorder: Recorder) { + private compileUnitTestImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder) { let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); let compiler = new Compiler(node, pandaGen, this, recorder); - if (CmdOptions.isModules() && ts.isSourceFile(node) && scope instanceof ModuleScope) { + if ( + CmdOptions.isModules() && + ts.isSourceFile(node) && + scope instanceof ModuleScope + ) { setImport(recorder.getImportStmts(), scope, pandaGen); setExportBinding(recorder.getExportStmts(), scope, pandaGen); } @@ -300,12 +331,16 @@ export class CompilerDriver { } let recorder = new Recorder(node, topLevelScope, this, enableTypeRecord, isTsFile); recorder.record(); - + addVariableToScope(recorder, enableTypeRecord); let postOrderVariableScopes = this.postOrderAnalysis(topLevelScope); for (let variableScope of postOrderVariableScopes) { - this.addCompilationUnit(variableScope.getBindingNode(), variableScope, recorder); + this.addCompilationUnit( + variableScope.getBindingNode(), + variableScope, + recorder + ); } return recorder; @@ -337,6 +372,12 @@ export class CompilerDriver { return idx; } + getRecoderFuncName(funcName: string): string { + let recoderName: string = this.getRecoderName(); + funcName = `${recoderName}.${funcName}` + return funcName; + } + /** * Internal name is used to indentify a function in panda file * Runtime uses this name to bind code and a Function object @@ -351,29 +392,27 @@ export class CompilerDriver { } else { let funcNode = node; name = (recorder.getScopeOfNode(funcNode)).getFuncName(); - if (name == '') { - return `#${this.getFuncId(funcNode)}#`; - } - - if (name == "func_main_0") { - return `#${this.getFuncId(funcNode)}#${name}`; - } - - let funcNameMap = recorder.getFuncNameMap(); - if (funcNameMap.has(name)) { - let freq = funcNameMap.get(name); - if (freq > 1) { - name = `#${this.getFuncId(funcNode)}#${name}`; - } + if (name == "") { + name = `#${this.getFuncId(funcNode)}#`; + } else if (name == "func_main_0") { + name = `#${this.getFuncId(funcNode)}#${name}`; } else { - throw new Error("the function name is missing from the name map"); - } + let funcNameMap = recorder.getFuncNameMap(); + if (funcNameMap.has(name)) { + let freq = funcNameMap.get(name); + if (freq > 1) { + name = `#${this.getFuncId(funcNode)}#${name}`; + } + } else { + throw new Error("the function name is missing from the name map"); + } - if (name.lastIndexOf(".") != -1) { - name = `#${this.getFuncId(funcNode)}#` + if (name.lastIndexOf(".") != -1) { + name = `#${this.getFuncId(funcNode)}#`; + } } } - return name; + return this.getRecoderFuncName(name); } getInternalNameForCtor(node: ts.ClassLikeDeclaration, ctor: ts.ConstructorDeclaration) { diff --git a/ts2panda/src/debuginfo.ts b/ts2panda/src/debuginfo.ts index 8e3b5c8fed..4b34759b1c 100644 --- a/ts2panda/src/debuginfo.ts +++ b/ts2panda/src/debuginfo.ts @@ -379,7 +379,7 @@ export class DebugInfo { public static setSourceFileDebugInfo(pandaGen: PandaGen, node: ts.SourceFile | ts.FunctionLikeDeclaration) { let sourceFile = jshelpers.getSourceFileOfNode(node); - pandaGen.setSourceFileDebugInfo(sourceFile.fileName); + pandaGen.setSourceFileName(sourceFile.fileName); if (CmdOptions.isDebugMode()) { if (ts.isSourceFile(node)) { diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index 19cc5075fa..81d4636622 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -14,79 +14,49 @@ */ import * as ts from "typescript"; +import { + checkIsGlobalDeclaration, + initiateTs2abcChildProcess, + isSourceFileFromLibrary +} from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { CompilerDriver } from "./compilerDriver"; import * as diag from "./diagnostic"; import { LOGD, LOGE } from "./log"; +import { PandaGen } from "./pandagen"; +import { Record } from "./pandasm"; import { Pass } from "./pass"; import { CacheExpander } from "./pass/cacheExpander"; import { ICPass } from "./pass/ICPass"; import { RegAlloc } from "./regAllocator"; -import { setGlobalStrict, setGlobalDeclare, isGlobalDeclare } from "./strictMode"; +import { setGlobalDeclare, setGlobalStrict } from "./strictMode"; +import { Ts2Panda } from "./ts2panda"; import { TypeChecker } from "./typeChecker"; -import { TypeRecorder } from "./typeRecorder"; import jshelpers = require("./jshelpers"); import path = require("path"); -function checkIsGlobalDeclaration(sourceFile: ts.SourceFile) { - for (let statement of sourceFile.statements) { - if (statement.modifiers) { - for (let modifier of statement.modifiers) { - if (modifier.kind === ts.SyntaxKind.ExportKeyword) { - return false; - } - } - } else if (statement.kind === ts.SyntaxKind.ExportAssignment) { - return false; - } else if (statement.kind === ts.SyntaxKind.ImportKeyword || statement.kind === ts.SyntaxKind.ImportDeclaration) { - return false; - } - } - return true; -} - -function generateDTs(node: ts.SourceFile, options: ts.CompilerOptions) { - let outputBinName = getOutputBinName(node); - let compilerDriver = new CompilerDriver(outputBinName); - setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, options)); - if (CmdOptions.isVariantBytecode()) { - LOGD("variant bytecode dump"); - let passes: Pass[] = [ - new CacheExpander(), - new ICPass(), - new RegAlloc() - ]; - compilerDriver.setCustomPasses(passes); - } - compilerDriver.compile(node); - compilerDriver.showStatistics(); -} - function main(fileNames: string[], options: ts.CompilerOptions) { - let program = ts.createProgram(fileNames, options); + let program: ts.Program = ts.createProgram(fileNames, options); let typeChecker = TypeChecker.getInstance(); typeChecker.setTypeChecker(program.getTypeChecker()); - if (CmdOptions.needRecordDtsType()) { - for (let sourceFile of program.getSourceFiles()) { - if (sourceFile.isDeclarationFile && !program.isSourceFileDefaultLibrary(sourceFile)) { - setGlobalDeclare(checkIsGlobalDeclaration(sourceFile)); - generateDTs(sourceFile, options); - } - } + let outputFileName: string = CmdOptions.getOutputFileName(); + let ts2abcProc: any + if (CmdOptions.isMergeAbcFiles()) { + ts2abcProc = initiateTs2abcChildProcess(outputFileName); } + generateDTs(program, outputFileName, options, ts2abcProc); + let emitResult = program.emit( - undefined, - undefined, - undefined, - undefined, + undefined, undefined, undefined, undefined, { before: [ (ctx: ts.TransformationContext) => { return (node: ts.SourceFile) => { - let outputBinName = getOutputBinName(node); - let compilerDriver = new CompilerDriver(outputBinName); + let recoderName: string = getRecoderName(node.fileName); + let outputBinName = getOutputFileName(node, outputFileName); + let compilerDriver = new CompilerDriver(outputBinName, ts2abcProc, recoderName); compilerDriver.compileForSyntaxCheck(node); return node; } @@ -95,55 +65,24 @@ function main(fileNames: string[], options: ts.CompilerOptions) { after: [ (ctx: ts.TransformationContext) => { return (node: ts.SourceFile) => { - if (ts.getEmitHelpers(node)) { - const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); - const text: string = printer.printNode(ts.EmitHint.Unspecified, node, node); - let newNode = ts.createSourceFile(node.fileName, text, options.target!); - node = newNode; - } - let outputBinName = getOutputBinName(node); - let compilerDriver = new CompilerDriver(outputBinName); - setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, options)); - if (CmdOptions.isVariantBytecode()) { - LOGD("variant bytecode dump"); - let passes: Pass[] = [ - new CacheExpander(), - new ICPass(), - new RegAlloc() - ]; - compilerDriver.setCustomPasses(passes); - } - compilerDriver.compile(node); - compilerDriver.showStatistics(); - return node; + return ts2abcTransform(node, outputFileName, options, ts2abcProc); } } ] } ); - let allDiagnostics = ts - .getPreEmitDiagnostics(program) - .concat(emitResult.diagnostics); - - allDiagnostics.forEach(diagnostic => { - diag.printDiagnostic(diagnostic); - }); -} - -function getOutputBinName(node: ts.SourceFile) { - let outputBinName = CmdOptions.getOutputBinName(); - let fileName = node.fileName.substring(0, node.fileName.lastIndexOf('.')); - let inputFileName = CmdOptions.getInputFileName(); - if (/^win/.test(require('os').platform())) { - var inputFileTmps = inputFileName.split(path.sep); - inputFileName = path.posix.join(...inputFileTmps); + if (preDiagnostics(program, emitResult)) { + return; } - if (fileName != inputFileName) { - outputBinName = fileName + ".abc"; + if (!CmdOptions.isAssemblyMode()) { + if (CmdOptions.isMergeAbcFiles()) { + Ts2Panda.dumpCommonFields(ts2abcProc, outputFileName); + PandaGen.clearRecoders(); + PandaGen.clearLiteralArrayBuffer(); + } } - return outputBinName; } namespace Compiler { @@ -162,6 +101,87 @@ namespace Compiler { } } +function generateDTs(program: ts.Program, outputFileName: string, options: ts.CompilerOptions, ts2abcProc: any): void { + if (CmdOptions.needRecordDtsType()) { + for (let sourceFile of program.getSourceFiles()) { + if (sourceFile.isDeclarationFile && !isSourceFileFromLibrary(program, sourceFile)) { + setGlobalDeclare(checkIsGlobalDeclaration(sourceFile)); + ts2abcTransform(sourceFile, outputFileName, options, ts2abcProc); + } + } + } +} + +function ts2abcTransform(node: ts.SourceFile, outputFileName: string, options: ts.CompilerOptions, ts2abcProc: any): ts.SourceFile { + let sourceFileName: string = node.fileName; + let recoderName: string = getRecoderName(sourceFileName); + // console.error("-----------------sourceFileName: ", sourceFileName); + // console.error("-----------------recoderName: ", recoderName); + let recoder: Record = new Record(recoderName, sourceFileName); + let recoders: Array = PandaGen.getRecoders(); + recoders.push(recoder); + if (ts.getEmitHelpers(node)) { + const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); + const text: string = printer.printNode(ts.EmitHint.Unspecified, node, node); + let newNode = ts.createSourceFile(node.fileName, text, options.target!); + node = newNode; + } + let newOutputFileName: string = getOutputFileName(node, outputFileName); + let compilerDriver = new CompilerDriver(newOutputFileName, ts2abcProc, recoderName); + setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, options)); + if (CmdOptions.isVariantBytecode()) { + LOGD("variant bytecode dump"); + let passes: Pass[] = [ + new CacheExpander(), + new ICPass(), + new RegAlloc() + ]; + compilerDriver.setCustomPasses(passes); + } + compilerDriver.compile(node); + compilerDriver.showStatistics(); + return node; +} + +function preDiagnostics(program: ts.Program, emitResult: ts.EmitResult): boolean { + let hasDiagnostics: boolean = false; + let allDiagnostics: ts.Diagnostic[] = ts + .getPreEmitDiagnostics(program) + .concat(emitResult.diagnostics); + + allDiagnostics.forEach((diagnostic: ts.Diagnostic) => { + diag.printDiagnostic(diagnostic); + hasDiagnostics = true; + }); + return hasDiagnostics; +} + +function getRecoderName(sourceFileName: string): string { + let recoderName: string = sourceFileName.substring(0, sourceFileName.lastIndexOf(".")); + let recoderDirInfo: string[] = CmdOptions.getModulesDirMap(); + if (recoderDirInfo.length) { + let index: number = recoderDirInfo.indexOf(sourceFileName); + if (index !== -1) { + recoderName = recoderDirInfo[index + 1]; + } + } + + return recoderName; +} + +function getOutputFileName(node: ts.SourceFile, outputFileName: string): string { + let fileName = node.fileName.substring(0, node.fileName.lastIndexOf('.')); + let inputFileName = CmdOptions.getInputFileName(); + if (/^win/.test(require('os').platform())) { + var inputFileTmps = inputFileName.split(path.sep); + inputFileName = path.posix.join(...inputFileTmps); + } + if (fileName != inputFileName) { + outputFileName = fileName + ".abc"; + } + return outputFileName; +} + function run(args: string[], options?: ts.CompilerOptions): void { let parsed = CmdOptions.parseUserCmd(args); if (!parsed) { @@ -174,13 +194,13 @@ function run(args: string[], options?: ts.CompilerOptions): void { } } try { - let files: string[] = parsed.fileNames; - main(files.concat(CmdOptions.getIncludedFiles()), parsed.options); + main(parsed.fileNames, parsed.options); } catch (err) { if (err instanceof diag.DiagnosticError) { - let diagnostic = diag.getDiagnostic(err.code); + let diagError: diag.DiagnosticError = err; + let diagnostic: ts.DiagnosticMessage | undefined = diag.getDiagnostic(diagError.code); if (diagnostic != undefined) { - let diagnosticLog = diag.createDiagnostic(err.file, err.irnode, diagnostic, ...err.args); + let diagnosticLog = diag.createDiagnostic(diagError.file, diagError.irnode, diagnostic, ...diagError.args); diag.printDiagnostic(diagnosticLog); } } else if (err instanceof SyntaxError) { diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index d7b0bfceb7..7489dc598e 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -173,6 +173,7 @@ import { VariableAcessStore } from "./lexenv"; import { LOGE } from "./log"; +import { Record } from "./pandasm"; import { FunctionScope, LoopScope, @@ -200,12 +201,13 @@ export class PandaGen { // for debug info private variableDebugInfoArray: VariableDebugInfo[] = []; private firstStmt: ts.Statement | undefined; - private sourceFileDebugInfo: string = ""; + private sourceFileName: string = ""; private sourceCodeDebugInfo: string | undefined; private icSize: number = 0; private callType: number = 0; private static literalArrayBuffer: Array = new Array(); + private static recoders: Array = new Array(); constructor(internalName: string, parametersCount: number, scope: Scope | undefined = undefined) { this.internalName = internalName; @@ -246,12 +248,12 @@ export class PandaGen { this.sourceCodeDebugInfo = code; } - public getSourceFileDebugInfo() { - return this.sourceFileDebugInfo; + public getSourceFileName() { + return this.sourceFileName; } - public setSourceFileDebugInfo(sourceFile: string) { - this.sourceFileDebugInfo = sourceFile; + public setSourceFileName(sourceFile: string) { + this.sourceFileName = sourceFile; } static getLiteralArrayBuffer() { @@ -262,6 +264,14 @@ export class PandaGen { PandaGen.literalArrayBuffer = []; } + static getRecoders() { + return PandaGen.recoders; + } + + static clearRecoders() { + PandaGen.recoders = []; + } + getParameterLength() { if (this.scope instanceof FunctionScope) { return this.scope.getParameterLength(); diff --git a/ts2panda/src/pandasm.ts b/ts2panda/src/pandasm.ts index 565615a2f5..23cd07cb9c 100644 --- a/ts2panda/src/pandasm.ts +++ b/ts2panda/src/pandasm.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { DebugPosInfo, VariableDebugInfo } from "./debuginfo"; import { LiteralBuffer } from "./base/literal"; +import { DebugPosInfo, VariableDebugInfo } from "./debuginfo"; export class Metadata { public attribute: string; @@ -110,25 +110,16 @@ export class Function { export class Record { public name: string; - public whole_line: string; - public bound_left: number; - public bound_right: number; - public line_number: number; public metadata: Metadata; + public source_file: string; constructor( name: string, - whole_line: string, - bound_left: number, - bound_right: number, - line_number: number + source_file: string ) { this.name = name; - this.whole_line = whole_line; - this.bound_left = bound_left; - this.bound_right = bound_right; - this.line_number = line_number; this.metadata = new Metadata(); + this.source_file = source_file; } } diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index 982d1ab35d..f6eecb8fa9 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -13,7 +13,6 @@ * limitations under the License. */ -import { Ts2Panda } from "src/ts2panda"; import * as ts from "typescript"; import { Literal, LiteralBuffer, LiteralTag } from "../base/literal"; import { LReference } from "../base/lreference"; @@ -24,7 +23,11 @@ import { propertyKeyAsString, PropertyKind } from "../base/properties"; -import { getParameterLength4Ctor, getParamLengthOfFunc, isUndefinedIdentifier } from "../base/util"; +import { + getParameterLength4Ctor, + getParamLengthOfFunc, + isUndefinedIdentifier +} from "../base/util"; import { CacheList, getVregisterCache } from "../base/vregisterCache"; import { Compiler } from "../compiler"; import { createArrayFromElements } from "../expression/arrayLiteralExpression"; @@ -84,7 +87,8 @@ export function compileClassDeclaration(compiler: Compiler, stmt: ts.ClassLikeDe } if (ts.isMethodDeclaration(prop.getValue())) { - let methodLiteral = new Literal(LiteralTag.METHOD, compiler.getCompilerDriver().getFuncInternalName(prop.getValue(), compiler.getRecorder())); + let internalName = compiler.getCompilerDriver().getFuncInternalName(prop.getValue(), compiler.getRecorder()); + let methodLiteral = new Literal(LiteralTag.METHOD, internalName); let affiliateLiteral = new Literal(LiteralTag.METHODAFFILIATE, getParamLengthOfFunc(prop.getValue())); classBuffer.addLiterals(methodLiteral, affiliateLiteral); } else { @@ -233,7 +237,8 @@ function createClassLiteralBuf(compiler: Compiler, classBuffer: LiteralBuffer, let ctorNode = compiler.getRecorder().getCtorOfClass(stmt); let internalName = compiler.getCompilerDriver().getInternalNameForCtor(stmt, ctorNode); - + let recoderName: string = compiler.getCompilerDriver().getRecoderName(); + internalName = `${recoderName}.${internalName}` let pandaGen = compiler.getPandaGen(); let parameterLength = getParameterLength4Ctor(stmt); let buffIdx = classLiteralBuf.length - 1; diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index 6e0d6e7cd9..fde72b54d8 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -13,33 +13,36 @@ * limitations under the License. */ +import { writeFileSync } from "fs"; +import { LiteralBuffer } from "./base/literal"; +import { + escapeUnicode, + getRangeStartVregPos, + isRangeInst, + terminateWritePipe +} from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { DebugPosInfo } from "./debuginfo"; import { - Imm, - IRNode, - Label, - OperandType, - VReg + Imm, + IRNode, + Label, + OperandType, + VReg } from "./irnodes"; import { LOGD } from "./log"; import { PandaGen } from "./pandagen"; import { - CatchTable, - DeclaredSymbol2Type, - ExportedSymbol2Type, - Function, - Ins, - Signature + CatchTable, + DeclaredSymbol2Type, + ExportedSymbol2Type, + Function, + Ins, + Record, + Signature, + TypeOfVreg } from "./pandasm"; import { generateCatchTables } from "./statement/tryStatement"; -import { - escapeUnicode, - isRangeInst, - getRangeStartVregPos -} from "./base/util"; -import { TypeOfVreg } from "./pandasm"; -import { LiteralBuffer } from "./base/literal"; const dollarSign: RegExp = /\$/g; @@ -130,7 +133,7 @@ export class Ts2Panda { static dumpStringsArray(ts2abc: any) { let strings_arr = Array.from(Ts2Panda.strings); - strings_arr.forEach(function(str) { + strings_arr.forEach(function (str: string) { let strObject = { "type": JsonType.string, "string": str @@ -172,6 +175,10 @@ export class Ts2Panda { "literalArray": literalArray } let jsonLiteralArrUnicode = escapeUnicode(JSON.stringify(literalArrayObject, null, 2)); + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonLiteralArrUnicode; + } + jsonLiteralArrUnicode = "$" + jsonLiteralArrUnicode.replace(dollarSign, '#$') + "$"; if (CmdOptions.isEnableDebugLog()) { Ts2Panda.jsonString += jsonLiteralArrUnicode; @@ -180,6 +187,23 @@ export class Ts2Panda { }); } + static dumpRecoder(ts2abc: any): void { + let recoders: Record[] = PandaGen.getRecoders(); + + recoders.forEach(function (recoder: Record) { + let recoderObject = { + "type": JsonType.record, + "rec_body": recoder + } + let jsonRecoderUnicode = escapeUnicode(JSON.stringify(recoderObject, null, 2)); + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonRecoderUnicode; + } + jsonRecoderUnicode = "$" + jsonRecoderUnicode.replace(dollarSign, '#$') + "$"; + ts2abc.stdio[3].write(jsonRecoderUnicode + '\n'); + }); + } + static dumpCmdOptions(ts2abc: any): void { let options = { "type": JsonType.options, @@ -201,7 +225,7 @@ export class Ts2Panda { let funcName = pg.internalName; let funcSignature = Ts2Panda.getFuncSignature(pg); let funcInsnsAndRegsNum = Ts2Panda.getFuncInsnsAndRegsNum(pg); - let sourceFile = pg.getSourceFileDebugInfo(); + let sourceFile = pg.getSourceFileName(); let callType = pg.getCallType(); let typeRecord = pg.getLocals(); let typeInfo = new Array(); @@ -218,7 +242,7 @@ export class Ts2Panda { let exportedTypes = PandaGen.getExportedTypes(); let exportedSymbol2Types = exportedTypes.size == 0 ? undefined : new Array(); - if (funcName == "func_main_0") { + if (funcName.indexOf("func_main_0") !== -1) { exportedTypes.forEach((type: number, symbol: string) => { let exportedSymbol2Type = new ExportedSymbol2Type(symbol, type); exportedSymbol2Types!.push(exportedSymbol2Type); @@ -227,7 +251,7 @@ export class Ts2Panda { let declareddTypes = PandaGen.getDeclaredTypes(); let declaredSymbol2Types = declareddTypes.size == 0 ? undefined : new Array(); - if (funcName == "func_main_0") { + if (funcName.indexOf("func_main_0") !== -1) { declareddTypes.forEach((type: number, symbol: string) => { let declaredSymbol2Type = new DeclaredSymbol2Type(symbol, type); declaredSymbol2Types!.push(declaredSymbol2Type); @@ -288,4 +312,19 @@ export class Ts2Panda { Ts2Panda.strings.clear(); Ts2Panda.jsonString = ""; } + + static dumpCommonFields(ts2abcProc: any, outputFileName: string) { + Ts2Panda.dumpCmdOptions(ts2abcProc); + Ts2Panda.dumpStringsArray(ts2abcProc); + Ts2Panda.dumpConstantPool(ts2abcProc); + Ts2Panda.dumpRecoder(ts2abcProc); + + terminateWritePipe(ts2abcProc); + if (CmdOptions.isEnableDebugLog()) { + let jsonFileName = outputFileName.substring(0, outputFileName.lastIndexOf(".")).concat(".json"); + writeFileSync(jsonFileName, Ts2Panda.jsonString); + LOGD("Successfully generate ", `${jsonFileName}`); + } + Ts2Panda.clearDumpData(); + } } diff --git a/ts2panda/tests/lexenv.test.ts b/ts2panda/tests/lexenv.test.ts index 64bd73f9d4..f7a82c52ea 100644 --- a/ts2panda/tests/lexenv.test.ts +++ b/ts2panda/tests/lexenv.test.ts @@ -116,7 +116,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { it("test CompilerDriver.scanFunctions-with-empty", function () { let source: string = ``; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); recorder.record(); @@ -144,7 +145,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { var funcExpression = function() { } `; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); recorder.record(); @@ -191,7 +193,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { let source: string = ` `; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); @@ -215,7 +218,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { var funcExt = function() { } `; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); @@ -269,7 +273,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { }))) `; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); diff --git a/ts2panda/tests/utils/base.ts b/ts2panda/tests/utils/base.ts index 94b1a99f00..4c727a5164 100644 --- a/ts2panda/tests/utils/base.ts +++ b/ts2panda/tests/utils/base.ts @@ -143,7 +143,8 @@ export function compileAllSnippet(snippet: string, passes?: Pass[], literalBuffe let sourceFile = creatAstFromSnippet(snippet); jshelpers.bindSourceFile(sourceFile, {}); setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(sourceFile, compileOptions)); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest', undefined, recoderName); if (!passes) { passes = []; diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index b9918d6e0a..85408f6311 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -62,17 +62,11 @@ namespace { } // pandasm hellpers -static panda::pandasm::Record MakeRecordDefinition(const std::string &name, const std::string &wholeLine, - size_t boundLeft, size_t boundRight, size_t lineNumber) +static panda::pandasm::Record MakeRecordDefinition(const std::string &name) { auto record = panda::pandasm::Record( name, - LANG_EXT, - boundLeft, - boundRight, - wholeLine, - IS_DEFINED, - lineNumber); + LANG_EXT); return record; } @@ -287,28 +281,7 @@ static panda::pandasm::Record ParseRecord(const Json::Value &record) recordName = record["name"].asString(); } - std::string wholeLine = ""; - if (record.isMember("whole_line") && record["whole_line"].isString()) { - wholeLine = ParseString(record["whole_line"].asString()); - } - - int boundLeft = -1; - if (record.isMember("bound_left") && record["bound_left"].isInt()) { - boundLeft = record["bound_left"].asInt(); - } - - int boundRight = -1; - if (record.isMember("bound_right") && record["bound_right"].isInt()) { - boundRight = record["bound_right"].asInt(); - } - - int lineNumber = -1; - if (record.isMember("line_number") && record["line_number"].isInt()) { - lineNumber = record["line_number"].asInt(); - } - - auto pandaRecord = MakeRecordDefinition(recordName, wholeLine, static_cast(boundLeft), - static_cast(boundRight), static_cast(lineNumber)); + auto pandaRecord = MakeRecordDefinition(recordName); if (record.isMember("metadata") && record["metadata"].isObject()) { auto metadata = record["metadata"]; @@ -320,6 +293,10 @@ static panda::pandasm::Record ParseRecord(const Json::Value &record) } } + if (record.isMember("source_file") && record["source_file"].isString()) { + pandaRecord.source_file = record["source_file"].asString(); + } + return pandaRecord; } -- Gitee