diff --git a/ts2panda/src/base/typeSystem.ts b/ts2panda/src/base/typeSystem.ts index a33eae14df4d0540b754f7c195e952e5383003e6..380dbba1b147f6d997660f36a585e9792d36f957 100644 --- a/ts2panda/src/base/typeSystem.ts +++ b/ts2panda/src/base/typeSystem.ts @@ -129,6 +129,10 @@ export class TypeSummary extends BaseType { this.setTypeArrayBuffer(this, this.preservedIndex); } + public getPreservedIndex() { + return this.preservedIndex; + } + transfer2LiteralBuffer(): LiteralBuffer { let countBuf = new LiteralBuffer(); let summaryLiterals: Array = new Array(); diff --git a/ts2panda/src/base/util.ts b/ts2panda/src/base/util.ts index 8d35cf6f42d56c8736f34f217ef60033c3290487..d608a9ca3c2075d2c876c06df9ff3d112946ec6f 100644 --- a/ts2panda/src/base/util.ts +++ b/ts2panda/src/base/util.ts @@ -26,6 +26,8 @@ import { import * as jshelpers from "../jshelpers"; import { LOGD } from "../log"; import { isFunctionLikeDeclaration } from "../syntaxCheckHelper"; +import { CmdOptions } from "../cmdOptions"; +import { CompilerDriver } from "../compilerDriver"; export function containSpreadElement(args?: ts.NodeArray): boolean { if (!args) { @@ -293,3 +295,7 @@ export function setPos(node: ts.Node) { }); return node; } + +export function getRecordTypeFlag(recordType: boolean) { + return recordType && CmdOptions.needRecordType() && CompilerDriver.isTsFile; +} \ No newline at end of file diff --git a/ts2panda/src/compilerDriver.ts b/ts2panda/src/compilerDriver.ts index 85c8b8356680bcc3dcf83ab4fb744abc25278d1d..296f0aaa6ec8326f47cc3cb138319fb24c83a5e9 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -17,7 +17,7 @@ import { writeFileSync } from "fs"; import * as ts from "typescript"; import { addVariableToScope } from "./addVariable2Scope"; import { AssemblyDumper } from "./assemblyDumper"; -import { hasDefaultKeywordModifier, hasExportKeywordModifier, initiateTs2abc, listenChildExit, listenErrorEvent, terminateWritePipe } from "./base/util"; +import { hasDefaultKeywordModifier, hasExportKeywordModifier, initiateTs2abc, listenChildExit, listenErrorEvent, terminateWritePipe, getRecordTypeFlag } from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { Compiler @@ -185,6 +185,7 @@ export class CompilerDriver { Ts2Panda.dumpStringsArray(ts2abcProc); Ts2Panda.dumpConstantPool(ts2abcProc); Ts2Panda.dumpModuleRecords(ts2abcProc); + Ts2Panda.dumpTypeInfoRecord(ts2abcProc, true) terminateWritePipe(ts2abcProc); if (CmdOptions.isEnableDebugLog()) { @@ -289,12 +290,11 @@ export class CompilerDriver { topLevelScope = new GlobalScope(node); } - let enableTypeRecord = recordType && CmdOptions.needRecordType() && CompilerDriver.isTsFile; - if (enableTypeRecord) { - TypeRecorder.createInstance(); - } + let enableTypeRecord = getRecordTypeFlag(recordType); + this.setTypeInfoBeforeRecord(enableTypeRecord); let recorder = new Recorder(node, topLevelScope, this, enableTypeRecord, CompilerDriver.isTsFile, syntaxCheckStatus); recorder.record(); + this.setTypeInfoAfterRecord(enableTypeRecord); if (topLevelScope instanceof ModuleScope) { topLevelScope.module().setModuleEnvironment(topLevelScope); } @@ -406,4 +406,22 @@ export class CompilerDriver { parametersCount += decl.parameters.length; return parametersCount; } + + private setTypeInfoBeforeRecord(enableTypeRecord: boolean) { + if (enableTypeRecord) { + TypeRecorder.createInstance(); + } + } + + private setTypeInfoAfterRecord(enableTypeRecord: boolean) { + if (enableTypeRecord) { + TypeRecorder.getInstance().setTypeSummary(); + if (CmdOptions.enableTypeLog()) { + TypeRecorder.getInstance().getLog(); + } + } else { + PandaGen.clearLiteralArrayBuffer(); + } + + } } diff --git a/ts2panda/src/recorder.ts b/ts2panda/src/recorder.ts index cc1f90981faddfb4ec33354a94447889324d6d69..e3ba10ca90838821142f396a2929c62704838865 100644 --- a/ts2panda/src/recorder.ts +++ b/ts2panda/src/recorder.ts @@ -89,14 +89,6 @@ export class Recorder { this.setParent(this.node); this.setScopeMap(this.node, this.scope); this.recordInfo(this.node, this.scope); - if (this.recordType) { - TypeRecorder.getInstance().setTypeSummary(); - if (CmdOptions.enableTypeLog()) { - TypeRecorder.getInstance().getLog(); - } - } else { - PandaGen.clearLiteralArrayBuffer(); - } return this.node; } diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index dd7fe6cbbd13631fa31fc7a240cce460179ffede..6c83c1654a1f53bdb668a1bba3679adeb3d52b02 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -47,6 +47,9 @@ import { import { LiteralBuffer } from "./base/literal"; import { CompilerDriver } from "./compilerDriver"; import { ModuleScope } from "./scope"; +import { getRecordTypeFlag } from "./base/util"; +import { TypeSummary } from "./base/typeSystem"; +import { TypeRecorder } from "./typeRecorder"; const dollarSign: RegExp = /\$/g; @@ -56,7 +59,8 @@ const JsonType = { "string": 2, "literal_arr": 3, "module": 4, - "options": 5 + "options": 5, + 'type_info': 6 }; export class Ts2Panda { static strings: Set = new Set(); @@ -321,6 +325,28 @@ export class Ts2Panda { }); } + static dumpTypeInfoRecord(ts2abc: any, recordType: boolean): void { + let enableTypeRecord = getRecordTypeFlag(recordType); + let typeSummaryIndex = 0; + if (enableTypeRecord) { + typeSummaryIndex = TypeRecorder.getInstance().getTypeSummaryIndex(); + } + let typeInfo = { + 'tf': enableTypeRecord, + 'tsi': typeSummaryIndex + } + let typeInfoObject = { + 't': JsonType.type_info, + 'ti': typeInfo + }; + let jsonModuleUnicode = escapeUnicode(JSON.stringify(typeInfoObject, null, 2)); + jsonModuleUnicode = "$" + jsonModuleUnicode.replace(dollarSign, '#$') + "$"; + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonModuleUnicode; + } + ts2abc.stdio[3].write(jsonModuleUnicode + '\n'); + } + static clearDumpData() { Ts2Panda.strings.clear(); Ts2Panda.jsonString = ""; diff --git a/ts2panda/src/typeRecorder.ts b/ts2panda/src/typeRecorder.ts index ee243525279c458b0411fb32bbd6e0b1641ddf11..4c836e391a3afb00b7d1ac36100f59e4948edb2a 100644 --- a/ts2panda/src/typeRecorder.ts +++ b/ts2panda/src/typeRecorder.ts @@ -53,6 +53,10 @@ export class TypeRecorder { this.typeSummary.setInfo(this.countUserDefinedTypeSet(), this.anonymousReExport); } + public getTypeSummaryIndex() { + return this.typeSummary.getPreservedIndex(); + } + public addUserDefinedTypeSet(index: number) { this.userDefinedTypeSet.add(index); } diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 62cfa4b8e3724a5c266388b1bface31f760589f8..19708da2e46947529284debba54f94023e9a72ee 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -1059,6 +1059,30 @@ static void ParseSingleModule(const Json::Value &rootValue, panda::pandasm::Prog prog.literalarray_table.emplace(std::to_string(g_literalArrayCount++), std::move(moduleLiteralarrayInstance)); } +static void ParseSingleTypeInfo(const Json::Value &rootValue, panda::pandasm::Program &prog) +{ + auto typeInfoRecord = rootValue["ti"]; + auto typeFlag = typeInfoRecord["tf"].asBool(); + auto typeSummaryIndex = typeInfoRecord["tsi"].asUInt(); + auto ecmaTypeInfoRecord = panda::pandasm::Record("_ESTypeInfoRecord", LANG_EXT); + ecmaTypeInfoRecord.metadata->SetAccessFlags(panda::ACC_PUBLIC); + + auto typeFlagField = panda::pandasm::Field(LANG_EXT); + typeFlagField.name = "typeFlag"; + typeFlagField.type = panda::pandasm::Type("u8", 0); + typeFlagField.metadata->SetValue(panda::pandasm::ScalarValue::Create( + static_cast(typeFlag))); + ecmaTypeInfoRecord.field_list.emplace_back(std::move(typeFlagField)); + auto typeSummaryIndexField = panda::pandasm::Field(LANG_EXT); + typeSummaryIndexField.name = "typeSummaryIndex"; + typeSummaryIndexField.type = panda::pandasm::Type("u32", 0); + typeSummaryIndexField.metadata->SetValue(panda::pandasm::ScalarValue::Create( + static_cast(typeSummaryIndex))); + ecmaTypeInfoRecord.field_list.emplace_back(std::move(typeSummaryIndexField)); + + prog.record_table.emplace(ecmaTypeInfoRecord.name, std::move(ecmaTypeInfoRecord)); +} + static int ParseSmallPieceJson(const std::string &subJson, panda::pandasm::Program &prog) { Json::Value rootValue; @@ -1105,6 +1129,12 @@ static int ParseSmallPieceJson(const std::string &subJson, panda::pandasm::Progr ParseOptions(rootValue, prog); break; } + case static_cast(JsonType::TYPEINFO): { + if (rootValue.isMember("ti") && rootValue["ti"].isObject()) { + ParseSingleTypeInfo(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 15ffe044222ae6be5f35d70d4c9dae098d76d63f..9a08c1569ce795591977f908f8150465b66c5b8b 100644 --- a/ts2panda/ts2abc/ts2abc.h +++ b/ts2panda/ts2abc/ts2abc.h @@ -34,7 +34,8 @@ enum class JsonType { STRING, LITERALBUFFER, MODULE, - OPTIONS + OPTIONS, + TYPEINFO }; constexpr int RETURN_SUCCESS = 0;