From 939be667896726af484af756413c1d9f6aa0a7ac Mon Sep 17 00:00:00 2001 From: gavin1012_hw Date: Mon, 12 Dec 2022 17:24:46 +0800 Subject: [PATCH] fixed 48e251a from https://gitee.com/gavin1012_hw/ark_ts2abc/pulls/759 Support Import Json in hap compiling Issue:I65UI0 Signed-off-by: gavin1012_hw Change-Id: I1e3afb973a92c826aa27cc20b3a5b9727107c9e4 --- es2panda/compiler/core/compilerContext.cpp | 9 ++--- es2panda/compiler/core/compilerContext.h | 13 +++++-- es2panda/compiler/core/compilerImpl.cpp | 2 +- es2panda/compiler/core/emitter/emitter.cpp | 16 +++++++++ es2panda/compiler/core/emitter/emitter.h | 1 + es2panda/es2panda.cpp | 12 +++++++ ts2panda/scripts/diagnosticMessages.json | 2 +- ts2panda/src/cmdOptions.ts | 2 +- ts2panda/src/compilerDriver.ts | 9 ++++- ts2panda/src/index.ts | 41 +++++++++++++++++----- ts2panda/src/syntaxChecker.ts | 2 +- ts2panda/src/ts2panda.ts | 18 +++++++++- ts2panda/ts2abc/ts2abc.cpp | 21 +++++++++++ ts2panda/ts2abc/ts2abc.h | 3 +- 14 files changed, 128 insertions(+), 23 deletions(-) diff --git a/es2panda/compiler/core/compilerContext.cpp b/es2panda/compiler/core/compilerContext.cpp index 5120ab97ad..32d6a6e3d8 100644 --- a/es2panda/compiler/core/compilerContext.cpp +++ b/es2panda/compiler/core/compilerContext.cpp @@ -21,11 +21,12 @@ namespace panda::es2panda::compiler { CompilerContext::CompilerContext(binder::Binder *binder, bool isDebug, bool isDebuggerEvaluateExpressionMode, - bool isMergeAbc, bool isTypeExtractorEnabled, std::string sourceFile, - std::string pkgName, util::StringView recordName) + bool isMergeAbc, bool isTypeExtractorEnabled, bool isJsonInputFile, + std::string sourceFile, std::string pkgName, util::StringView recordName) : binder_(binder), isDebug_(isDebug), isDebuggerEvaluateExpressionMode_(isDebuggerEvaluateExpressionMode), - isMergeAbc_(isMergeAbc), isTypeExtractorEnabled_(isTypeExtractorEnabled), sourceFile_(sourceFile), - pkgName_(pkgName), emitter_(std::make_unique(this)), recordName_(recordName) + isMergeAbc_(isMergeAbc), isTypeExtractorEnabled_(isTypeExtractorEnabled), isJsonInputFile_(isJsonInputFile), + sourceFile_(sourceFile), pkgName_(pkgName), recordName_(recordName), + emitter_(std::make_unique(this)) { } diff --git a/es2panda/compiler/core/compilerContext.h b/es2panda/compiler/core/compilerContext.h index 4332c9a1b2..2cd7829f8d 100644 --- a/es2panda/compiler/core/compilerContext.h +++ b/es2panda/compiler/core/compilerContext.h @@ -43,7 +43,7 @@ class Emitter; class CompilerContext { public: CompilerContext(binder::Binder *binder, bool isDebug, bool isDebuggerEvaluateExpressionMode, - bool isMergeAbc, bool isTypeExtractorEnabled, std::string sourceFile, + bool isMergeAbc, bool isTypeExtractorEnabled, bool isJsonInputFile, std::string sourceFile, std::string pkgName, util::StringView recordName); NO_COPY_SEMANTIC(CompilerContext); NO_MOVE_SEMANTIC(CompilerContext); @@ -110,7 +110,7 @@ public: return hotfixHelper_; } - util::StringView &RecordName() + const util::StringView &RecordName() const { return recordName_; } @@ -127,6 +127,11 @@ public: void SetTypeRecorder(extractor::TypeRecorder *recorder); + bool IsJsonInputFile() const + { + return isJsonInputFile_; + } + private: binder::Binder *binder_; int32_t literalBufferIdx_ {0}; @@ -136,12 +141,14 @@ private: bool isMergeAbc_; // For Type Extractor bool isTypeExtractorEnabled_; + // true when input file is json file + bool isJsonInputFile_; extractor::TypeRecorder *recorder_ {}; std::string sourceFile_; std::string pkgName_; + util::StringView recordName_; std::unique_ptr emitter_; util::Hotfix *hotfixHelper_ {nullptr}; - util::StringView recordName_; }; } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/compilerImpl.cpp b/es2panda/compiler/core/compilerImpl.cpp index bd7ce35e97..4245749bfa 100644 --- a/es2panda/compiler/core/compilerImpl.cpp +++ b/es2panda/compiler/core/compilerImpl.cpp @@ -40,7 +40,7 @@ panda::pandasm::Program *CompilerImpl::Compile(parser::Program *program, const e const std::string &debugInfoSourceFile, const std::string &pkgName) { CompilerContext context(program->Binder(), options.isDebug, options.isDebuggerEvaluateExpressionMode, - options.mergeAbc, options.typeExtractor, debugInfoSourceFile, pkgName, + options.mergeAbc, options.typeExtractor, false, debugInfoSourceFile, pkgName, program->RecordName()); if (hotfixHelper_ != nullptr) { diff --git a/es2panda/compiler/core/emitter/emitter.cpp b/es2panda/compiler/core/emitter/emitter.cpp index 027200e901..b4185b1f7a 100644 --- a/es2panda/compiler/core/emitter/emitter.cpp +++ b/es2panda/compiler/core/emitter/emitter.cpp @@ -287,6 +287,11 @@ Emitter::Emitter(const CompilerContext *context) prog_ = new panda::pandasm::Program(); prog_->lang = LANG_EXT; + if (context->IsJsonInputFile()) { + GenJsonContentRecord(context); + return; + } + // For Type Extractor // Global record to show type extractor is enabled or not GenTypeInfoRecord(); @@ -335,6 +340,17 @@ void Emitter::GenESTypeAnnotationRecord() const prog_->record_table.emplace(typeAnnotationRecord.name, std::move(typeAnnotationRecord)); } +void Emitter::GenJsonContentRecord(const CompilerContext *context) +{ + rec_ = new panda::pandasm::Record(std::string(context->RecordName()), panda::panda_file::SourceLang::ECMASCRIPT); + auto jsonContentField = panda::pandasm::Field(panda::panda_file::SourceLang::ECMASCRIPT); + jsonContentField.name = "jsonFileContent"; + jsonContentField.type = panda::pandasm::Type("u32", 0); + jsonContentField.metadata->SetValue(panda::pandasm::ScalarValue::Create( + static_cast(context->SourceFile()))); + rec_->field_list.emplace_back(std::move(jsonContentField)); +} + void Emitter::AddFunction(FunctionEmitter *func, CompilerContext *context) { std::lock_guard lock(m_); diff --git a/es2panda/compiler/core/emitter/emitter.h b/es2panda/compiler/core/emitter/emitter.h index 3ef8387bbe..1f7d2253ed 100644 --- a/es2panda/compiler/core/emitter/emitter.h +++ b/es2panda/compiler/core/emitter/emitter.h @@ -113,6 +113,7 @@ public: const LiteralBuffer *buff); static void DumpAsm(const panda::pandasm::Program *prog); panda::pandasm::Program *Finalize(bool dumpDebugInfo, util::Hotfix *hotfixHelper); + void GenJsonContentRecord(const CompilerContext *context); private: void SetCommonjsField(bool isCommonjs); diff --git a/es2panda/es2panda.cpp b/es2panda/es2panda.cpp index f0e266ae0f..7c42974334 100644 --- a/es2panda/es2panda.cpp +++ b/es2panda/es2panda.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,13 @@ Compiler::~Compiler() delete compiler_; } +panda::pandasm::Program *createJsonContentProgram(std::string src, std::string rname) +{ + panda::es2panda::compiler::CompilerContext context(nullptr, false, false, false, false, true, + src, "", util::StringView(rname)); + return context.GetEmitter()->Finalize(false, nullptr); +} + panda::pandasm::Program *Compiler::Compile(const SourceFile &input, const CompilerOptions &options, util::SymbolTable *symbolTable) { @@ -62,6 +70,10 @@ panda::pandasm::Program *Compiler::Compile(const SourceFile &input, const Compil std::string pkgName(input.pkgName); parser::ScriptKind kind(input.scriptKind); + if (fname.substr(fname.find_last_of(".") + 1) == "json") { + return createJsonContentProgram(src, rname); + } + bool needDumpSymbolFile = !options.hotfixOptions.dumpSymbolTable.empty(); bool needGeneratePatch = options.hotfixOptions.generatePatch && !options.hotfixOptions.symbolTable.empty(); util::Hotfix *hotfixHelper = nullptr; diff --git a/ts2panda/scripts/diagnosticMessages.json b/ts2panda/scripts/diagnosticMessages.json index 0d6bc041ee..e40e026c01 100644 --- a/ts2panda/scripts/diagnosticMessages.json +++ b/ts2panda/scripts/diagnosticMessages.json @@ -551,7 +551,7 @@ "Getter must not have any formal parameters": { "category": "Error", "code": 19006 - }, + }, "Class declaration not allowed in statement position": { "category": "Error", "code": 19007 diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 8ea83e1e18..0c7169dd9b 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -55,7 +55,7 @@ export const ts2pandaOptions = [ { name: 'package-name', type: String, defaultValue: "", description: "specify the package that the compiling file belongs to." }, { name: 'output-proto', type: Boolean, defaultValue: false, description: "Output protoBin file. Default: false" }, { name: 'merge-abc', type: Boolean, defaultValue: false, description: "Compile as merge abc" }, - { name: 'input-file', type: String, defaultValue: "", description: "A file containing a list of source files to be compiled. Each line of this file should be constructed in such format: fileName;recordName;moduleType;sourceFile" }, + { name: 'input-file', type: String, defaultValue: "", description: "A file containing a list of source files to be compiled. Each line of this file should be constructed in such format: fileName;recordName;moduleType;sourceFile;packageName" }, ] diff --git a/ts2panda/src/compilerDriver.ts b/ts2panda/src/compilerDriver.ts index 2998d8008f..16c0921f81 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { writeFileSync } from "fs"; +import { readFileSync, writeFileSync } from "fs"; import * as ts from "typescript"; import { addVariableToScope } from "./addVariable2Scope"; import { AssemblyDumper } from "./assemblyDumper"; @@ -239,6 +239,13 @@ export class CompilerDriver { PandaGen.clearLiteralArrayBuffer(); } + dumpInputJsonFileContent(ts2abcProc: any, jsonFileName: string, recordName: string): void { + Ts2Panda.dumpRecord(ts2abcProc, recordName); + Ts2Panda.dumpCmdOptions(ts2abcProc); + Ts2Panda.dumpInputJsonFileContent(ts2abcProc, readFileSync(jsonFileName).toString()); + Ts2Panda.dumpOutputFileName(ts2abcProc, jsonFileName.substring(0, jsonFileName.lastIndexOf(".")).concat(".abc")); + } + private compileImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder): void { diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index ed7dcf5336..23f5a202a9 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -64,11 +64,12 @@ function generateDTs(node: ts.SourceFile, options: ts.CompilerOptions) { compilerDriver.showStatistics(); } -function main(fileNames: string[], options: ts.CompilerOptions, cmdArgsSet?: Map) { +function main(fileNames: string[], options: ts.CompilerOptions, inputJsonFiles?: string[], cmdArgsSet?: Map) { const host = ts.createCompilerHost(options); if (!CmdOptions.needGenerateTmpFile()) { host.writeFile = () => {}; } + let program = ts.createProgram(fileNames, options, host); let typeChecker = TypeChecker.getInstance(); typeChecker.setTypeChecker(program.getTypeChecker()); @@ -92,11 +93,8 @@ function main(fileNames: string[], options: ts.CompilerOptions, cmdArgsSet?: Map return; } - let initCompilerDriver; - if (CmdOptions.isCompileFilesList()) { - initCompilerDriver = new CompilerDriver("", ""); - initCompilerDriver.initiateTs2abcChildProcess(["--multi-programs-pipe"]); - } + let initCompilerDriver = new CompilerDriver("", ""); + let initTs2abcProcessState = false; let emitResult = program.emit( undefined, @@ -133,6 +131,10 @@ function main(fileNames: string[], options: ts.CompilerOptions, cmdArgsSet?: Map (ctx: ts.TransformationContext) => { return (node: ts.SourceFile) => { if (CmdOptions.isCompileFilesList()) { + if (!initTs2abcProcessState) { + initCompilerDriver.initiateTs2abcChildProcess(["--multi-programs-pipe"]); + initTs2abcProcessState = true; + } let specifiedCmdArgs = cmdArgsSet.get(node.fileName); if (specifiedCmdArgs == undefined) { return node; @@ -174,6 +176,18 @@ function main(fileNames: string[], options: ts.CompilerOptions, cmdArgsSet?: Map ); if (CmdOptions.isCompileFilesList()) { + if (!initTs2abcProcessState) { + initCompilerDriver.initiateTs2abcChildProcess(["--multi-programs-pipe"]); + } + for (let i = 0; i < inputJsonFiles.length; i++) { + let jsonFileName = inputJsonFiles[i]; + let originProcessArgs = process.argv.slice(0); + Array.prototype.splice.apply(process.argv, cmdArgsSet.get(jsonFileName)); + //@ts-ignore + CmdOptions.options = commandLineArgs(ts2pandaOptions, { partial: true }); + process.argv = originProcessArgs.slice(0); + initCompilerDriver.dumpInputJsonFileContent(initCompilerDriver.getTs2abcProcess(), jsonFileName, CmdOptions.getRecordName()); + } terminateWritePipe(initCompilerDriver.getTs2abcProcess()); } @@ -201,6 +215,7 @@ function transformSourcefilesList(parsed: ts.ParsedCommandLine | undefined) { if (sourceFileInfoArray.length == 0) return; let files: string[] = parsed.fileNames; + let inputJsonFiles: string[] = []; let cmdArgsSet = new Map(); for (let i = 0; i < sourceFileInfoArray.length; i++) { @@ -211,7 +226,13 @@ function transformSourcefilesList(parsed: ts.ParsedCommandLine | undefined) { } let inputFileName = sourceFileInfo[0]; - files.unshift(inputFileName); + let inputFileSuffix = inputFileName.substring(inputFileName.lastIndexOf(".") + 1); + if (inputFileSuffix == "json") { + inputJsonFiles.push(inputFileName); + } else { + files.unshift(inputFileName); + } + let specifiedCmdArgs = ["--record-name", sourceFileInfo[1]]; switch (sourceFileInfo[2]) { case "esm": @@ -220,8 +241,10 @@ function transformSourcefilesList(parsed: ts.ParsedCommandLine | undefined) { case "commonjs": specifiedCmdArgs.push.apply(specifiedCmdArgs, ["-c"]); break; + case "na": + break; default: - throw new Error("The third info should be \"esm\" or \"commonjs\"."); + throw new Error("The third info should be \"esm\", \"commonjs\" or \"na\"."); } specifiedCmdArgs.push.apply(specifiedCmdArgs, ["--source-file", sourceFileInfo[3]]); specifiedCmdArgs.push.apply(specifiedCmdArgs, ["--package-name", sourceFileInfo[4]]); @@ -231,7 +254,7 @@ function transformSourcefilesList(parsed: ts.ParsedCommandLine | undefined) { cmdArgsSet.set(inputFileName, specifiedCmdArgs); } - main(files, parsed.options, cmdArgsSet); + main(files, parsed.options, inputJsonFiles, cmdArgsSet); } function getDtsFiles(libDir: string): string[] { diff --git a/ts2panda/src/syntaxChecker.ts b/ts2panda/src/syntaxChecker.ts index 10ff9e1498..69750aa96d 100644 --- a/ts2panda/src/syntaxChecker.ts +++ b/ts2panda/src/syntaxChecker.ts @@ -152,7 +152,7 @@ function hasDuplicateEntryInScope(decl1: Decl, decl2: Decl, scope: Scope) { * var a; * function a() {}; * } - * + * * eg2. * if (true) { * function a() {}; diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index f7504ddd47..f6d17a09f2 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -69,7 +69,8 @@ const JsonType = { "options": 5, 'type_info': 6, 'record_name': 7, - 'output_filename': 8 + 'output_filename': 8, + 'input_json_file_content': 9 }; export class Ts2Panda { static strings: Set = new Set(); @@ -493,6 +494,21 @@ export class Ts2Panda { ts2abc.stdio[3].write(jsonTypeInfoUnicode + '\n'); } + static dumpInputJsonFileContent(ts2abc: any, inputJsonFileContent: string): void { + let inputJsonFileContentObject = { + "t": JsonType.input_json_file_content, + "ijfc": inputJsonFileContent + } + + let jsonInputJsonFileContentUnicode = escapeUnicode(JSON.stringify(inputJsonFileContentObject, null, 2)); + jsonInputJsonFileContentUnicode = "$" + jsonInputJsonFileContentUnicode.replace(dollarSign, '#$') + "$"; + jsonInputJsonFileContentUnicode = jsonInputJsonFileContentUnicode.replace(starSign, '#*'); + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonInputJsonFileContentUnicode; + } + ts2abc.stdio[3].write(jsonInputJsonFileContentUnicode + '\n'); + } + static dumpOutputFileName(ts2abc: any, outputFileName: string): void { let outputFileNameObject = { "t": JsonType.output_filename, diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 0c5593e91c..81b6348936 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -1090,6 +1090,21 @@ static void SetPackageName(const std::string &packageName, panda::pandasm::Progr } } +static void ParseInputJsonFileContent(const Json::Value &rootValue, panda::pandasm::Program &prog) +{ + auto iter = prog.record_table.find(g_recordName); + if (iter != prog.record_table.end()) { + auto &rec = iter->second; + + auto inputJsonFileContentField = panda::pandasm::Field(LANG_EXT); + inputJsonFileContentField.name = "jsonFileContent"; + inputJsonFileContentField.type = panda::pandasm::Type("u32", 0); + inputJsonFileContentField.metadata->SetValue(panda::pandasm::ScalarValue::Create( + static_cast(rootValue["ijfc"].asString()))); + rec.field_list.emplace_back(std::move(inputJsonFileContentField)); + } +} + static void ParseSingleStr(const Json::Value &rootValue, panda::pandasm::Program &prog) { auto strArr = rootValue["s"]; @@ -1356,6 +1371,12 @@ static int ParseSmallPieceJson(const std::string &subJson, panda::pandasm::Progr } break; } + case static_cast(JsonType::INPUTJSONFILECONTENT): { + if (rootValue.isMember("ijfc") && rootValue["ijfc"].isString()) { + ParseInputJsonFileContent(rootValue, prog); + } + break; + } default: { std::cerr << "Unreachable json type: " << type << std::endl; return RETURN_FAILED; diff --git a/ts2panda/ts2abc/ts2abc.h b/ts2panda/ts2abc/ts2abc.h index dfcee1e337..e1d9bf08e6 100644 --- a/ts2panda/ts2abc/ts2abc.h +++ b/ts2panda/ts2abc/ts2abc.h @@ -38,7 +38,8 @@ enum class JsonType { OPTIONS, TYPEINFO, RECORDNAME, - OUTPUTFILENAME + OUTPUTFILENAME, + INPUTJSONFILECONTENT }; constexpr int RETURN_SUCCESS = 0; -- Gitee