diff --git a/doc/cn/CompilerPhaseDescription.md b/doc/cn/CompilerPhaseDescription.md index 00e9f947ff2c70299264a74bc2894266705639c9..3bd1244dac0613fb660ec67930f0caa46e0bf328 100644 --- a/doc/cn/CompilerPhaseDescription.md +++ b/doc/cn/CompilerPhaseDescription.md @@ -15,7 +15,7 @@ 不同于MapleModulePhase,MapleFunctionPhase是一个模板类,主要是因为Maple中有不同层次的函数级IR。中端的优化phase和后端的优化phase都是该类的派生类。 -### phae的内存管理 +### phase的内存管理 方舟编译器的phasemanager可以对内存进行有效的管理,以便每个phase可以保留可能被其他phase依赖的分析结果;以及丢弃失效的结果。每个phasemanager中提供一个AnalysisDataManager类(多线程时,每个线程对应一个AnalysisDataManager)用来存储分析结果。为了实现这个功能,每个phase需要实现GetAnalysisDependence函数。如下: diff --git a/src/MapleFE/ast2cpp/src/a2c_util.cpp b/src/MapleFE/ast2cpp/src/a2c_util.cpp index 91fc4b5a43c7f6b81cda106054af857529131c35..4b272e6859280d7968b8ff8a53d6b22318e58e66 100644 --- a/src/MapleFE/ast2cpp/src/a2c_util.cpp +++ b/src/MapleFE/ast2cpp/src/a2c_util.cpp @@ -43,21 +43,31 @@ std::string ImportedFiles::GetTargetFilename(TreeNode *node) { ImportNode *ImportedFiles::VisitImportNode(ImportNode *node) { std::string name = GetTargetFilename(node->GetTarget()); - if (!name.empty()) - mFilenames.push_back(name); - for (unsigned i = 0; i < node->GetPairsNum(); ++i) + if (!name.empty()) { + mFilenames.push_back(name); + } + for (unsigned i = 0; i < node->GetPairsNum(); ++i) { if (auto x = node->GetPair(i); x->IsSingle()) { std::string s = GetTargetFilename(x->GetBefore()); if (!s.empty()) mFilenames.push_back(s); } + } + for (unsigned i = 0; i < node->GetPairsNum(); i++) { + XXportAsPairNode *pair = node->GetPair(i); + (void) AstVisitor::VisitTreeNode(pair); + } return node; } ExportNode *ImportedFiles::VisitExportNode(ExportNode *node) { std::string name = GetTargetFilename(node->GetTarget()); if (!name.empty()) - mFilenames.push_back(name); + mFilenames.push_back(name); + for (unsigned i = 0; i < node->GetPairsNum(); i++) { + XXportAsPairNode *pair = node->GetPair(i); + (void) AstVisitor::VisitTreeNode(pair); + } return node; } } diff --git a/src/MapleFE/ast2cpp/src/cpp_definition.cpp b/src/MapleFE/ast2cpp/src/cpp_definition.cpp index e35dea4fc22fc567a8fdd87cb75bf014db52612d..3531572c726b56cb82983b1597a7edbe044f3ce2 100644 --- a/src/MapleFE/ast2cpp/src/cpp_definition.cpp +++ b/src/MapleFE/ast2cpp/src/cpp_definition.cpp @@ -31,7 +31,7 @@ std::string CppDef::EmitCtorInstance(ClassNode *c) { proto.insert(0, "&"s, 0, std::string::npos); } str = "\n// Init class ctor as a static class field for "+ thisClass+ "\n"s; - str += thisClass + "::Ctor "s + thisClass+"::ctor = " + thisClass + "::Ctor("s +ctor+","s+proto+","+prototypeProto+");\n\n"s; + str += thisClass + "::Ctor "s + thisClass+"::ctor("s +ctor+","s+proto+","+prototypeProto+");\n\n"s; // piggy back generation of static field definition for (unsigned i = 0; i < c->GetFieldsNum(); ++i) { diff --git a/src/MapleFE/ast2cpp/src/emitter.cpp b/src/MapleFE/ast2cpp/src/emitter.cpp index d961d2ae76a4630fc10af20a9368a55cd0150789..91d66224c3e5bdb68c36f9b2c63390a471771bdd 100644 --- a/src/MapleFE/ast2cpp/src/emitter.cpp +++ b/src/MapleFE/ast2cpp/src/emitter.cpp @@ -594,7 +594,7 @@ std::string Emitter::EmitImportNode(ImportNode *node) { str += " from "s + s; else { auto p = node->GetParent(); - if (p && p->IsField()) + if (p && (p->IsField() || p->IsTypeOf())) str += '(' + s + ')'; else str += s; diff --git a/src/MapleFE/astopt/include/ast_ti.h b/src/MapleFE/astopt/include/ast_ti.h index 7832681c3275079b80bd6e075f3e018f4094ae3b..79b28276a02a355a26ab2072625d2d2016de58e2 100644 --- a/src/MapleFE/astopt/include/ast_ti.h +++ b/src/MapleFE/astopt/include/ast_ti.h @@ -163,8 +163,10 @@ class TypeInferVisitor : public TypeInferBaseVisitor { ArrayElementNode *VisitArrayElementNode(ArrayElementNode *node); ArrayLiteralNode *VisitArrayLiteralNode(ArrayLiteralNode *node); + AsTypeNode *VisitAsTypeNode(AsTypeNode *node); BinOperatorNode *VisitBinOperatorNode(BinOperatorNode *node); CallNode *VisitCallNode(CallNode *node); + CastNode *VisitCastNode(CastNode *node); ClassNode *VisitClassNode(ClassNode *node); CondBranchNode *VisitCondBranchNode(CondBranchNode *node); DeclNode *VisitDeclNode(DeclNode *node); diff --git a/src/MapleFE/astopt/src/ast_scp.cpp b/src/MapleFE/astopt/src/ast_scp.cpp index cd2f46565c0a93b42e1347cbb093c649f5d161e9..4c101784c778d909c5d39093f6bc9addd1218e53 100644 --- a/src/MapleFE/astopt/src/ast_scp.cpp +++ b/src/MapleFE/astopt/src/ast_scp.cpp @@ -477,7 +477,14 @@ UserTypeNode *BuildScopeVisitor::VisitUserTypeNode(UserTypeNode *node) { if (p->IsScope()) { // normal type decl - AddType(scope, node); + // check if it is already in typetable + TreeNode *id = node->GetId(); + if (id) { + TreeNode *decl = scope->FindTypeOf(id->GetStrIdx()); + if (!decl) { + AddType(scope, node); + } + } } } return node; diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index 8325ff3b0d55651bd86e7161b441534fee4c791a..1a21909423fe2ae3fb470f6b6cc464e1b07c2daa 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -1066,6 +1066,28 @@ CallNode *TypeInferVisitor::VisitCallNode(CallNode *node) { return node; } +CastNode *TypeInferVisitor::VisitCastNode(CastNode *node) { + (void) AstVisitor::VisitCastNode(node); + TreeNode *dest = node->GetDestType(); + SetTypeId(node, dest); + return node; +} + +AsTypeNode *TypeInferVisitor::VisitAsTypeNode(AsTypeNode *node) { + (void) AstVisitor::VisitAsTypeNode(node); + TreeNode *dest = node->GetType(); + SetTypeId(node, dest); + + TreeNode *parent = node->GetParent(); + if (parent) { + // pass to parent, need refine if multiple AsTypeNode + if (parent->GetAsTypesNum() == 1 && parent->GetAsTypeAtIndex(0) == node) { + SetTypeId(parent, dest); + } + } + return node; +} + ClassNode *TypeInferVisitor::VisitClassNode(ClassNode *node) { if (mFlags & FLG_trace_1) std::cout << "Visiting ClassNode, id=" << node->GetNodeId() << "..." << std::endl; UpdateTypeId(node, TY_Class); @@ -1444,26 +1466,15 @@ IdentifierNode *TypeInferVisitor::VisitIdentifierNode(IdentifierNode *node) { decl = mHandler->FindDecl(node, true); } } else if (node == fld) { - if (upper->IsIdentifier()) { - if (upper->IsThis()) { - decl = upper; + TreeNode *cls = gTypeTable.GetTypeFromTypeIdx(upper->GetTypeIdx()); + if (cls) { + scope = cls->GetScope(); + + // for imported decl, need trace down the import/export chain + if (decl && mXXport->IsImportedDeclId(mHandler->GetHidx(), decl->GetNodeId())) { + decl = scope->FindExportedDeclOf(node->GetStrIdx()); } else { - decl = mHandler->FindDecl(static_cast(upper), true); - } - if (decl) { - unsigned tidx = decl->GetTypeIdx(); - if (tidx) { - TreeNode *declt = gTypeTable.GetTypeFromTypeIdx(tidx); - scope = declt->GetScope(); - } else { - scope = decl->GetScope(); - } - // for imported decl, need trace down the import/export chain - if (mXXport->IsImportedDeclId(mHandler->GetHidx(), decl->GetNodeId())) { - decl = scope->FindExportedDeclOf(node->GetStrIdx()); - } else { - decl = scope->FindDeclOf(node->GetStrIdx()); - } + decl = scope->FindDeclOf(node->GetStrIdx()); } } } else { @@ -1537,15 +1548,22 @@ StructNode *TypeInferVisitor::VisitStructNode(StructNode *node) { } if (node->GetProp() == SProp_TSEnum) { TypeId tid = TY_None; + unsigned tidx = 0; for (unsigned i = 0; i < node->GetFieldsNum(); ++i) { TreeNode *t = node->GetField(i); tid = MergeTypeId(tid, t->GetTypeId()); + tidx = MergeTypeIdx(tidx, t->GetTypeIdx()); } for (unsigned i = 0; i < node->GetFieldsNum(); ++i) { TreeNode *t = node->GetField(i); SetTypeId(t, tid); + SetTypeIdx(t, tidx); + } + TreeNode *id = node->GetStructId(); + if (id) { + SetTypeId(id, node->GetTypeId()); + SetTypeIdx(id, node->GetTypeIdx()); } - SetTypeId(node, tid); } (void) AstVisitor::VisitStructNode(node); return node; diff --git a/src/MapleFE/astopt/src/ast_xxport.cpp b/src/MapleFE/astopt/src/ast_xxport.cpp index 6b7695186d209b3692a31415434b5100b96a524c..43e28d11735ba302410b7119e846d659b049cc58 100644 --- a/src/MapleFE/astopt/src/ast_xxport.cpp +++ b/src/MapleFE/astopt/src/ast_xxport.cpp @@ -435,6 +435,14 @@ void AST_XXport::UpdateDependency(unsigned hidx, TreeNode *node) { // update handler dependency map unsigned dep = GetHandleIdxFromStrIdx(stridx); mHandlerIdx2DependentHandlerIdxMap[hidx].insert(dep); + + if (node->IsImport()) { + Module_Handler *handler = mASTHandler->GetModuleHandler(dep); + ModuleNode *module = handler->GetASTModule(); + + node->SetTypeId(module->GetTypeId()); + node->SetTypeIdx(module->GetTypeIdx()); + } } } diff --git a/src/MapleFE/test/typescript/ts2cxx-test.sh b/src/MapleFE/test/typescript/ts2cxx-test.sh index cc5fd7add326539b9d2672fb7a3affab09fe1035..33897fa18fd607b8c978d4a89637679d88b8f66d 100755 --- a/src/MapleFE/test/typescript/ts2cxx-test.sh +++ b/src/MapleFE/test/typescript/ts2cxx-test.sh @@ -41,22 +41,14 @@ for f in $list; do (set -x while true; do $TS2AST $f || { echo "(ts2ast)$f" >> ts2cpp.failures.out; break; } - dep=$(grep "^[ei][xm]port.* from " "$f" | sed "s/^ *[ei][xm]port.* from .\([^'\"]*\).*/\1.cpp/" | sort -u) - if [ -z $dep ]; then -# dep=$(grep "^[ei][xm]port.* require" "$f" | sed "s/^ *[ei][xm]port.* require *\([^();\"]*\)/\1.cpp/" | sort -u) - dep=$(grep "^[ei][xm]port.* require" "$f" | sed "s/^ *[ei][xm]port.* require(\"\(.*\)\");/\1.cpp/" | sort -u) - fi -echo $dep > xxx + dep=$(sed 's/[ ,:|]\(import(\)/\n\1/g' "$f" | grep -E "^ *[ei][xm]port.*( from |require|\( *['\"])" | \ + sed -r "s/^ *[ei][xm]port.*( from |require *\(|\() *['\"]([^'\"]*).*/\2.cpp/" | sort -u) for cpp in $dep; do ts=$(sed 's/\.cpp/.ts/' <<< "$cpp") $TS2AST $ts - dep="$dep "$(grep "^[ei][xm]port.* from " "$ts" | sed "s/^ *[ei][xm]port.* from .\([^'\"]*\).*/\1.cpp/" | sort -u) - if [ -z $dep ]; then -# dep=$(grep "^[ei][xm]port.* require" "$f" | sed "s/^ *[ei][xm]port.* require *\([^();\"]*\)/\1.cpp/" | sort -u) - dep=$(grep "^[ei][xm]port.* require" "$f" | sed "s/^ *[ei][xm]port.* require(\"\(.*\)\");/\1.cpp/" | sort -u) - fi + dep="$dep "$(sed 's/[ ,:|]\(import(\)/\n\1/g' "$ts" | grep -E "^ *[ei][xm]port.*( from |require|\( *['\"])" | \ + sed -r "s/^ *[ei][xm]port.*( from |require *\(|\() *['\"]([^'\"]*).*/\2.cpp/" | sort -u) done -echo $dep >> xxx dep=$(echo $dep | xargs -n1 | sort -u) $AST2CPP $f.ast || { echo "(ast2cpp)$f" >> ts2cpp.failures.out; break; } g++ -std=c++17 -g -I$RTINC -I$ASTINC $t.cpp $RTSRC/*.cpp $dep -o $t.out || { echo "(g++)$f" >> ts2cpp.failures2.out; break; } diff --git a/src/MapleFE/test/typescript/unit_tests/class-deco4.ts b/src/MapleFE/test/typescript/unit_tests/class-deco4.ts index 063acd21db109419d51de9c374457bf468f8ee9d..9174fb8079897328c8aaf3a4c02bbcb31e156753 100644 --- a/src/MapleFE/test/typescript/unit_tests/class-deco4.ts +++ b/src/MapleFE/test/typescript/unit_tests/class-deco4.ts @@ -8,7 +8,7 @@ function class_deco(name: string): Function { @class_deco('Klass') class Klass { data: - {} = {}; + {n: number} = {n : 123}; public dump (value: number) { switch (value) { diff --git a/src/MapleFE/test/typescript/unit_tests/class-deco4.ts.result b/src/MapleFE/test/typescript/unit_tests/class-deco4.ts.result index 83a2de736128fb8098ef382a2d46279afe2ed516..b52fdf7351455c144a4bf82ff4623a2dd1db1b91 100644 --- a/src/MapleFE/test/typescript/unit_tests/class-deco4.ts.result +++ b/src/MapleFE/test/typescript/unit_tests/class-deco4.ts.result @@ -1,7 +1,7 @@ Matched 38 tokens. -Matched 84 tokens. -Matched 94 tokens. -Matched 101 tokens. +Matched 90 tokens. +Matched 100 tokens. +Matched 107 tokens. ============= Module =========== == Sub Tree == func class_deco(name) throws: @@ -13,7 +13,7 @@ func class_deco(name) throws: == Sub Tree == class Klass Fields: - data= {} + data= {n:123} Instance Initializer: Constructors: Methods: diff --git a/src/MapleFE/test/typescript/unit_tests/export-func-as-import.ts b/src/MapleFE/test/typescript/unit_tests/export-func-as-import.ts new file mode 100644 index 0000000000000000000000000000000000000000..93c7e958e8c08c795b8787ff8b80ac3b156fd671 --- /dev/null +++ b/src/MapleFE/test/typescript/unit_tests/export-func-as-import.ts @@ -0,0 +1,4 @@ +function func(n: string, o?: string): Promise { + return new Promise((resolve, reject) => { resolve("OK"); }); +} +export { func as import }; diff --git a/src/MapleFE/test/typescript/unit_tests/import-as-prop-name.ts b/src/MapleFE/test/typescript/unit_tests/import-as-prop-name.ts new file mode 100644 index 0000000000000000000000000000000000000000..98e0884aa562bc94c8fecdaf61e1bab04a2a9749 --- /dev/null +++ b/src/MapleFE/test/typescript/unit_tests/import-as-prop-name.ts @@ -0,0 +1,3 @@ +declare interface Load { + import(n: string, o?: string): Promise; +} diff --git a/src/MapleFE/test/typescript/unit_tests/import-promise.ts b/src/MapleFE/test/typescript/unit_tests/import-promise.ts new file mode 100644 index 0000000000000000000000000000000000000000..9e3ee013a75a19c62f9517bd469905b43edaf889 --- /dev/null +++ b/src/MapleFE/test/typescript/unit_tests/import-promise.ts @@ -0,0 +1,2 @@ +import("./M").then(() => { console.log("Completed") } ); +