From db0b798273d0ff401d8c1117479640835b6ac880 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Tue, 28 Dec 2021 14:56:56 -0500 Subject: [PATCH 1/8] fix handling of StrIndexSig fields as they are not real fields --- src/MapleFE/astopt/src/ast_info.cpp | 18 ++++++++++++------ src/MapleFE/astopt/src/ast_scp.cpp | 9 +++------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/MapleFE/astopt/src/ast_info.cpp b/src/MapleFE/astopt/src/ast_info.cpp index 2daae92390..41ae37a99e 100644 --- a/src/MapleFE/astopt/src/ast_info.cpp +++ b/src/MapleFE/astopt/src/ast_info.cpp @@ -717,8 +717,10 @@ StructNode *ClassStructVisitor::VisitStructNode(StructNode *node) { } mInfo->SetStrIdx2Struct(node->GetStrIdx(), node); for (unsigned i = 0; i < node->GetFieldsNum(); ++i) { - if (auto t = node->GetField(i)) { - mHandler->AddDirectField(t); + if (TreeNode *t = node->GetField(i)) { + if (!t->IsStrIndexSig()) { + mHandler->AddDirectField(t); + } } } } else if (mInfo->GetPass() == 1) { @@ -745,8 +747,10 @@ ClassNode *ClassStructVisitor::VisitClassNode(ClassNode *node) { if (mInfo->GetPass() == 0) { mInfo->SetStrIdx2Struct(node->GetStrIdx(), node); for (unsigned i = 0; i < node->GetFieldsNum(); ++i) { - if (auto t = node->GetField(i)) { - mHandler->AddDirectField(t); + if (TreeNode *t = node->GetField(i)) { + if (!t->IsStrIndexSig()) { + mHandler->AddDirectField(t); + } } } } else if (mInfo->GetPass() == 1) { @@ -773,8 +777,10 @@ InterfaceNode *ClassStructVisitor::VisitInterfaceNode(InterfaceNode *node) { if (mInfo->GetPass() == 0) { mInfo->SetStrIdx2Struct(node->GetStrIdx(), node); for (unsigned i = 0; i < node->GetFieldsNum(); ++i) { - if (auto t = node->GetField(i)) { - mHandler->AddDirectField(t); + if (TreeNode *t = node->GetField(i)) { + if (!t->IsStrIndexSig()) { + mHandler->AddDirectField(t); + } } } } else if (mInfo->GetPass() == 1) { diff --git a/src/MapleFE/astopt/src/ast_scp.cpp b/src/MapleFE/astopt/src/ast_scp.cpp index b73272917e..9bb2a2efaa 100644 --- a/src/MapleFE/astopt/src/ast_scp.cpp +++ b/src/MapleFE/astopt/src/ast_scp.cpp @@ -305,8 +305,7 @@ ClassNode *BuildScopeVisitor::VisitClassNode(ClassNode *node) { for(unsigned i = 0; i < node->GetFieldsNum(); i++) { TreeNode *fld = node->GetField(i); if (fld->IsStrIndexSig()) { - StrIndexSigNode *sn = static_cast(fld); - fld = sn->GetKey(); + continue; } if (fld->IsIdentifier()) { AddDecl(scope, fld); @@ -337,8 +336,7 @@ InterfaceNode *BuildScopeVisitor::VisitInterfaceNode(InterfaceNode *node) { for(unsigned i = 0; i < node->GetFieldsNum(); i++) { TreeNode *fld = node->GetField(i); if (fld->IsStrIndexSig()) { - StrIndexSigNode *sn = static_cast(fld); - fld = sn->GetKey(); + continue; } if (fld->IsIdentifier()) { AddDecl(scope, fld); @@ -367,8 +365,7 @@ StructNode *BuildScopeVisitor::VisitStructNode(StructNode *node) { for(unsigned i = 0; i < node->GetFieldsNum(); i++) { TreeNode *fld = node->GetField(i); if (fld->IsStrIndexSig()) { - StrIndexSigNode *sn = static_cast(fld); - fld = sn->GetKey(); + continue; } if (fld && fld->IsIdentifier()) { AddDecl(scope, fld); -- Gitee From cb232432814dd8de2cb5d2ac49b076c573b64ab7 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Tue, 28 Dec 2021 15:02:39 -0500 Subject: [PATCH 2/8] add API GetModuleHandler(TreeNode *node) improve handling of field literal --- src/MapleFE/astopt/include/ast_handler.h | 8 +++- src/MapleFE/astopt/include/ast_ti.h | 3 ++ src/MapleFE/astopt/src/ast_handler.cpp | 18 ++++++-- src/MapleFE/astopt/src/ast_scp.cpp | 8 +++- src/MapleFE/astopt/src/ast_ti.cpp | 52 +++++++++++++++++------- 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/MapleFE/astopt/include/ast_handler.h b/src/MapleFE/astopt/include/ast_handler.h index d6ca33098d..a0a2494149 100644 --- a/src/MapleFE/astopt/include/ast_handler.h +++ b/src/MapleFE/astopt/include/ast_handler.h @@ -65,6 +65,7 @@ class AST_Handler { // vector of all AST modules SmallVector mModuleHandlers; + Module_Handler *GetModuleHandler(ModuleNode *module); public: // mapping of mModuleHandlers index with its corresponding filename as its key @@ -78,8 +79,8 @@ class AST_Handler { AstOpt *GetAstOpt() {return mAstOpt;} void SetAstOpt(AstOpt *opt) {mAstOpt = opt;} - Module_Handler *GetModuleHandler(unsigned i); - Module_Handler *GetModuleHandler(ModuleNode *module); + Module_Handler *GetModuleHandler(unsigned i) {return mModuleHandlers.ValueAtIndex(i);} + Module_Handler *GetModuleHandler(TreeNode *node); unsigned GetSize() {return mSize;} @@ -222,6 +223,9 @@ class Module_Handler { return node; } + Module_Handler *GetModuleHandler(unsigned i) {return mASTHandler->GetModuleHandler(i);} + Module_Handler *GetModuleHandler(TreeNode *node) {return mASTHandler->GetModuleHandler(node);} + // API to check a node is c++ field which satisfy both: // 1. direct field // 2. its name is valid in c++ diff --git a/src/MapleFE/astopt/include/ast_ti.h b/src/MapleFE/astopt/include/ast_ti.h index 2871d9ae9e..7832681c32 100644 --- a/src/MapleFE/astopt/include/ast_ti.h +++ b/src/MapleFE/astopt/include/ast_ti.h @@ -61,6 +61,9 @@ class BuildIdDirectFieldVisitor : public AstVisitor { : AstVisitor((f & FLG_trace_1) && base), mHandler(h), mFlags(f) {} ~BuildIdDirectFieldVisitor() = default; + TreeNode *GetParentVarClass(TreeNode *node); + Module_Handler *GetHandler(TreeNode *node); + FieldNode *VisitFieldNode(FieldNode *node); FieldLiteralNode *VisitFieldLiteralNode(FieldLiteralNode *node); ArrayElementNode *VisitArrayElementNode(ArrayElementNode *node); diff --git a/src/MapleFE/astopt/src/ast_handler.cpp b/src/MapleFE/astopt/src/ast_handler.cpp index def1fb7d68..d6cf4cdc94 100644 --- a/src/MapleFE/astopt/src/ast_handler.cpp +++ b/src/MapleFE/astopt/src/ast_handler.cpp @@ -51,10 +51,6 @@ MemPool *Module_Handler::GetMemPool() { return mASTHandler->GetMemPool(); } -Module_Handler *AST_Handler::GetModuleHandler(unsigned i) { - return mModuleHandlers.ValueAtIndex(i); -} - Module_Handler *AST_Handler::GetModuleHandler(ModuleNode *module) { for (unsigned i = 0; i < mModuleHandlers.GetNum(); i++) { Module_Handler *h = mModuleHandlers.ValueAtIndex(i); @@ -65,6 +61,20 @@ Module_Handler *AST_Handler::GetModuleHandler(ModuleNode *module) { return NULL; } +Module_Handler *AST_Handler::GetModuleHandler(TreeNode *node) { + ASTScope *scp = node->GetScope(); + while (!scp->GetTree()->IsModule()) { + scp = scp->GetParent(); + } + TreeNode *mod = scp->GetTree(); + Module_Handler *h = NULL; + if (mod && mod->IsModule()) { + h = GetModuleHandler(static_cast(mod)); + } + + return h; +} + HandlerIndex AST_Handler::GetHandlerIndex(const char *filename) { if (mModuleHandlerMap.find(filename) == mModuleHandlerMap.end()) return HandlerNotFound; diff --git a/src/MapleFE/astopt/src/ast_scp.cpp b/src/MapleFE/astopt/src/ast_scp.cpp index 9bb2a2efaa..33374c22e9 100644 --- a/src/MapleFE/astopt/src/ast_scp.cpp +++ b/src/MapleFE/astopt/src/ast_scp.cpp @@ -388,6 +388,7 @@ StructNode *BuildScopeVisitor::VisitStructNode(StructNode *node) { StrIndexSigNode *sig = node->GetStrIndexSig(); if (sig) { TreeNode *fld = sig->GetKey(); + sig->SetStrIdx(fld->GetStrIdx()); if (fld && fld->IsIdentifier()) { AddDecl(scope, fld); } @@ -498,8 +499,11 @@ UserTypeNode *BuildScopeVisitor::VisitUserTypeNode(UserTypeNode *node) { TypeAliasNode *BuildScopeVisitor::VisitTypeAliasNode(TypeAliasNode *node) { ASTScope *scope = mScopeStack.top(); BuildScopeBaseVisitor::VisitTypeAliasNode(node); - AddDecl(scope, node); - AddType(scope, node); + TreeNode *ut = node->GetId(); + if (ut->IsUserType()) { + TreeNode *id = static_cast(ut)->GetId(); + AddDecl(scope, id); + } return node; } diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index 642ad8e47a..89c439ace5 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -39,14 +39,6 @@ void TypeInfer::TypeInference() { BuildIdNodeToDeclVisitor visitor_build(mHandler, mFlags, true); visitor_build.Visit(module); - // build mDirectFieldSet - MSGNOLOC0("============== Build DirectFieldSet =============="); - BuildIdDirectFieldVisitor visitor_field(mHandler, mFlags, true); - visitor_field.Visit(module); - if (mFlags & FLG_trace_3) { - visitor_field.Dump(); - } - // type inference MSGNOLOC0("============== TypeInfer =============="); TypeInferVisitor visitor_ti(mHandler, mFlags, true); @@ -58,6 +50,14 @@ void TypeInfer::TypeInference() { visitor_ti.Visit(module); } + // build mDirectFieldSet + MSGNOLOC0("============== Build DirectFieldSet =============="); + BuildIdDirectFieldVisitor visitor_field(mHandler, mFlags, true); + visitor_field.Visit(module); + if (mFlags & FLG_trace_3) { + visitor_field.Dump(); + } + if (mFlags & FLG_trace_3) std::cout << "\n>>>>>> TypeInference() iterated " << count << " times\n" << std::endl; // share UserType @@ -103,15 +103,38 @@ FieldNode *BuildIdDirectFieldVisitor::VisitFieldNode(FieldNode *node) { return node; } +TreeNode *BuildIdDirectFieldVisitor::GetParentVarClass(TreeNode *node) { + TreeNode *n = node; + while (n && !n->IsModule()) { + unsigned tyidx = 0; + if (n->IsDecl()) { + tyidx = n->GetTypeIdx(); + } else if (n->IsBinOperator()) { + tyidx = n->GetTypeIdx(); + } + if (tyidx) { + return gTypeTable.GetTypeFromTypeIdx(tyidx); + } + n = n->GetParent(); + } + return NULL; +} + FieldLiteralNode *BuildIdDirectFieldVisitor::VisitFieldLiteralNode(FieldLiteralNode *node) { (void) AstVisitor::VisitFieldLiteralNode(node); TreeNode *name = node->GetFieldName(); IdentifierNode *field = static_cast(name); - TreeNode *decl = NULL; - decl = mHandler->FindDecl(field); - if (decl) { - mHandler->AddDirectField(field); - mHandler->AddDirectField(node); + TreeNode *decl = mHandler->FindDecl(field); + TreeNode *vtype = GetParentVarClass(decl); + if (vtype) { + // check if decl is a field of vtype + // note: vtype could be in different module + Module_Handler *h = mHandler->GetModuleHandler(vtype); + TreeNode *fld = h->GetINFO()->GetField(vtype->GetNodeId(), decl->GetStrIdx()); + if (fld) { + mHandler->AddDirectField(field); + mHandler->AddDirectField(node); + } } return node; } @@ -1212,8 +1235,7 @@ ImportNode *TypeInferVisitor::VisitImportNode(ImportNode *node) { TreeNode *fld = field->GetField(); if (upper->IsTypeIdModule()) { TreeNode *type = gTypeTable.GetTypeFromTypeIdx(upper->GetTypeIdx()); - ModuleNode *mod = static_cast(type); - Module_Handler *h = mHandler->GetASTHandler()->GetModuleHandler(mod); + Module_Handler *h = mHandler->GetModuleHandler(type); exported = mXXport->GetExportedNamedNode(h->GetHidx(), fld->GetStrIdx()); if (exported) { UpdateTypeId(bfnode, exported->GetTypeId()); -- Gitee From 77f4c387afcbb1e927115c83177997af54bd7cbc Mon Sep 17 00:00:00 2001 From: Wen HU Date: Wed, 29 Dec 2021 14:09:07 -0500 Subject: [PATCH 3/8] get scope from upper's type for field --- src/MapleFE/astopt/src/ast_ti.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index 89c439ace5..5040b31092 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -1442,12 +1442,17 @@ IdentifierNode *TypeInferVisitor::VisitIdentifierNode(IdentifierNode *node) { 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())) { - scope = decl->GetScope(); decl = scope->FindExportedDeclOf(node->GetStrIdx()); } else { - scope = decl->GetScope(); decl = scope->FindDeclOf(node->GetStrIdx()); } } -- Gitee From ec9d34c03186e8b9bb63090cea571f572a1e5b63 Mon Sep 17 00:00:00 2001 From: eching Date: Wed, 29 Dec 2021 11:36:47 -0800 Subject: [PATCH 4/8] Fix missing include path for newly added header which caused ts2cpp testcases to fail build. --- src/MapleFE/test/typescript/ts2cxx-test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MapleFE/test/typescript/ts2cxx-test.sh b/src/MapleFE/test/typescript/ts2cxx-test.sh index 598b802b4a..959d3121c7 100755 --- a/src/MapleFE/test/typescript/ts2cxx-test.sh +++ b/src/MapleFE/test/typescript/ts2cxx-test.sh @@ -6,6 +6,7 @@ MPLFEPATH=$(cd $(dirname $0)/../../; pwd) TSOUT=$MPLFEPATH/output/typescript RTSRC=$MPLFEPATH/ast2cpp/runtime/src RTINC=$MPLFEPATH/ast2cpp/runtime/include +ASTINC=$MPLFEPATH/astopt/include TS2AST=$TSOUT/bin/ts2ast AST2CPP=$TSOUT/bin/ast2cpp TSCSH=$(dirname $0)/tsc.sh @@ -48,7 +49,7 @@ for f in $list; do done dep=$(echo $dep | xargs -n1 | sort -u) $AST2CPP $f.ast || { echo "(ast2cpp)$f" >> ts2cpp.failures.out; break; } - g++ -std=c++17 -g -I$RTINC $t.cpp $RTSRC/*.cpp $dep -o $t.out || { echo "(g++)$f" >> ts2cpp.failures2.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; } ./$t.out 2>&1 > $f-run.out || { echo "(run)$f" >> ts2cpp.failures2.out; break; } $TSCSH $f diff $f-run.out $f-nodejs.out -- Gitee From ca1e4f19b99fb5ecb72186eac54cf0bf2f77217e Mon Sep 17 00:00:00 2001 From: yehandong Date: Wed, 29 Dec 2021 12:59:50 -0800 Subject: [PATCH 5/8] Handle more cases of ASI. --- .../unit_tests/semicolon-missing13.ts.result | 7 +++++ src/MapleFE/typescript/src/lang_spec.cpp | 29 ++++++++++++++----- 2 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 src/MapleFE/test/typescript/unit_tests/semicolon-missing13.ts.result diff --git a/src/MapleFE/test/typescript/unit_tests/semicolon-missing13.ts.result b/src/MapleFE/test/typescript/unit_tests/semicolon-missing13.ts.result new file mode 100644 index 0000000000..a2f1cd875b --- /dev/null +++ b/src/MapleFE/test/typescript/unit_tests/semicolon-missing13.ts.result @@ -0,0 +1,7 @@ +Matched 3 tokens. +Matched 9 tokens. +============= Module =========== +== Sub Tree == +console.log +== Sub Tree == +console.log(null) diff --git a/src/MapleFE/typescript/src/lang_spec.cpp b/src/MapleFE/typescript/src/lang_spec.cpp index e8721a226b..e175d3e5ba 100644 --- a/src/MapleFE/typescript/src/lang_spec.cpp +++ b/src/MapleFE/typescript/src/lang_spec.cpp @@ -511,17 +511,32 @@ bool TypescriptParser::TraverseASI(RuleTable *rule_table, // To simplify the code, I reused TraverseToken(). found = TraverseToken(semicolon, appeal, child); } else { - if (curr_token->mLineBegin && - prev_token->mLineEnd && - prev_token->IsSeparator()){ - if (prev_token->GetSepId() == SEP_Rbrace || - prev_token->GetSepId() == SEP_Rbrack || - prev_token->GetSepId() == SEP_Rparen) { + if (curr_token->mLineBegin && prev_token->mLineEnd) { + // If prev token (line end) is a separator + if (prev_token->IsSeparator() && + (prev_token->GetSepId() == SEP_Rbrace || + prev_token->GetSepId() == SEP_Rbrack || + prev_token->GetSepId() == SEP_Rparen)) { if (mTraceTable) { std::cout << "TraverseASI, Auto-insert one semicolon." << std::endl; } - return true; + found = true; } + + // if prev token is identifier or keyword AND the curr token is also id or keyword + // we can try to insert semicolon. A simple case is: + // a <-- we can insert semicolon + // console.log(); + if ( (prev_token->IsIdentifier() || prev_token->IsKeyword()) && + (curr_token->IsIdentifier() || curr_token->IsKeyword()) ){ + if (mTraceTable) { + std::cout << "TraverseASI, Auto-insert one semicolon." << std::endl; + } + found = true; + } + + if (found) + return found; } } -- Gitee From be5ccb58891981a3c17b2ada6d7cbe162c45f34f Mon Sep 17 00:00:00 2001 From: yehandong Date: Wed, 29 Dec 2021 13:11:17 -0800 Subject: [PATCH 6/8] Support one more case of nested TypeArray. --- .../unit_tests/index-signature-2.ts.result | 16 ++++++++++++++++ src/MapleFE/typescript/stmt.spec | 5 +++-- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 src/MapleFE/test/typescript/unit_tests/index-signature-2.ts.result diff --git a/src/MapleFE/test/typescript/unit_tests/index-signature-2.ts.result b/src/MapleFE/test/typescript/unit_tests/index-signature-2.ts.result new file mode 100644 index 0000000000..8d4f6fe7da --- /dev/null +++ b/src/MapleFE/test/typescript/unit_tests/index-signature-2.ts.result @@ -0,0 +1,16 @@ +Matched 12 tokens. +Matched 13 tokens. +Matched 36 tokens. +============= Module =========== +== Sub Tree == +class Klass + Fields: + number + Instance Initializer: + Constructors: + Methods: + LocalClasses: + LocalInterfaces: + +== Sub Tree == + type MyArray = Array diff --git a/src/MapleFE/typescript/stmt.spec b/src/MapleFE/typescript/stmt.spec index 45cac8ddaa..16eef2fa74 100644 --- a/src/MapleFE/typescript/stmt.spec +++ b/src/MapleFE/typescript/stmt.spec @@ -1705,8 +1705,9 @@ rule InferType : "infer" + Identifier rule TypeArray : ONEOF(PrimaryType + '[' + PrimaryExpression + ']', PrimaryType + '[' + TypeReference + ']', TypeArray + '[' + PrimaryExpression + ']', - PrimaryType + '[' + ConditionalType + ']') - attr.action.%1,%2,%3,%4 : BuildArrayElement(%1, %3) + PrimaryType + '[' + ConditionalType + ']', + PrimaryType + '[' + TypeArray + ']') + attr.action.%1,%2,%3,%4,%5 : BuildArrayElement(%1, %3) rule ImportedType : "import" + '(' + Literal + ')' attr.action : BuildImport() -- Gitee From c0f72009b1ee75c6091e34f9edc0e78f1e1ee74b Mon Sep 17 00:00:00 2001 From: Wen HU Date: Wed, 29 Dec 2021 16:59:15 -0500 Subject: [PATCH 7/8] restrict using contstructor to real types --- src/MapleFE/astopt/src/ast_ti.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index 5040b31092..c7c9572e5b 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -607,7 +607,8 @@ bool TypeInferVisitor::UpdateVarTypeWithInit(TreeNode *var, TreeNode *init) { } } else if (init->IsIdentifier()) { TreeNode *decl = mHandler->FindDecl(static_cast(init)); - if (decl && (decl->IsClass() || decl->GetTypeIdx() < (unsigned)TY_Max)) { + unsigned tidx = decl->GetTypeIdx(); + if (decl && (decl->IsClass() || (0 < tidx && tidx < (unsigned)TY_Max))) { SetTypeId(idnode, TY_Function); SetUpdated(); result = true; -- Gitee From 810a615a6672b627111b7dec192e03ebed2da698 Mon Sep 17 00:00:00 2001 From: Wen HU Date: Thu, 30 Dec 2021 14:41:01 -0500 Subject: [PATCH 8/8] add mechanism to exclude processing identifiers with language keywords: [java|typescript]/include/lang_keywords.def --- src/MapleFE/astopt/include/astopt.h | 8 ++ src/MapleFE/astopt/src/Makefile | 1 + src/MapleFE/astopt/src/ast_scp.cpp | 13 --- src/MapleFE/astopt/src/ast_ti.cpp | 20 ++-- src/MapleFE/astopt/src/astopt.cpp | 7 +- src/MapleFE/java/include/lang_keywords.def | 71 ++++++++++++ .../typescript/include/lang_keywords.def | 101 ++++++++++++++++++ 7 files changed, 201 insertions(+), 20 deletions(-) create mode 100644 src/MapleFE/java/include/lang_keywords.def create mode 100644 src/MapleFE/typescript/include/lang_keywords.def diff --git a/src/MapleFE/astopt/include/astopt.h b/src/MapleFE/astopt/include/astopt.h index 5e6704b48d..6a5fd6e144 100644 --- a/src/MapleFE/astopt/include/astopt.h +++ b/src/MapleFE/astopt/include/astopt.h @@ -22,6 +22,7 @@ #include #include +#include #include "ast_module.h" #include "ast.h" #include "gen_astvisitor.h" @@ -42,6 +43,9 @@ private: // nodeid to node map for all nodes in all modules std::unordered_map mNodeId2NodeMap; + // language keywords + std::unordered_set mLangKeywords; + // nodeid to handler map for all nodes in all modules std::unordered_map mNodeId2HandlerMap; @@ -67,6 +71,10 @@ public: Module_Handler *GetHandlerFromNodeId(unsigned nid) { return mNodeId2HandlerMap[nid]; } void AddNodeId2HandlerMap(unsigned nid, Module_Handler *h) { mNodeId2HandlerMap[nid] = h; } + + bool IsLangKeyword(TreeNode *node) { + return mLangKeywords.find(node->GetStrIdx()) != mLangKeywords.end(); + } }; class BuildNodeIdToNodeVisitor : public AstVisitor { diff --git a/src/MapleFE/astopt/src/Makefile b/src/MapleFE/astopt/src/Makefile index 58500cc4c2..3d61edb588 100644 --- a/src/MapleFE/astopt/src/Makefile +++ b/src/MapleFE/astopt/src/Makefile @@ -28,6 +28,7 @@ LIBOBJS :=$(patsubst $(BUILD)/main.o,,$(OBJS)) INCLUDES := -I $(MAPLEFE_ROOT)/shared/include \ -I $(MAPLEFE_ROOT)/astopt/include \ + -I $(MAPLEFE_ROOT)/$(SRCLANG)/include \ -I ${BUILDDIR}/ast_gen/shared TARGET=astopt.a diff --git a/src/MapleFE/astopt/src/ast_scp.cpp b/src/MapleFE/astopt/src/ast_scp.cpp index 33374c22e9..126a95b1b3 100644 --- a/src/MapleFE/astopt/src/ast_scp.cpp +++ b/src/MapleFE/astopt/src/ast_scp.cpp @@ -120,13 +120,6 @@ void BuildScopeVisitor::AddTypeAndDecl(ASTScope *scope, TreeNode *node) { AddDecl(scope, node); } -#define ADD_DECL(K) {\ - TreeNode *node = mHandler->NewTreeNode(); \ - unsigned idx = gStringPool.GetStrIdx(K); \ - node->SetStrIdx(idx); \ - AddDecl(scope, node); \ -} - void BuildScopeVisitor::InitInternalTypes() { // add primitive and builtin types to root scope ModuleNode *module = mHandler->GetASTModule(); @@ -152,12 +145,6 @@ void BuildScopeVisitor::InitInternalTypes() { console->AddMethod(log); log->SetScope(scp); AddDecl(scp, log); - - // add dummy decl for some keywords - ADD_DECL("undefined"); - ADD_DECL("null"); - ADD_DECL("Error"); - ADD_DECL("NonNullable"); } ClassNode *BuildScopeVisitor::AddClass(std::string name, unsigned tyidx) { diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index c7c9572e5b..8325ff3b0d 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -74,6 +74,9 @@ void TypeInfer::TypeInference() { // build up mNodeId2Decl by visiting each Identifier IdentifierNode *BuildIdNodeToDeclVisitor::VisitIdentifierNode(IdentifierNode *node) { + if (mHandler->GetAstOpt()->IsLangKeyword(node)) { + return node; + } (void) AstVisitor::VisitIdentifierNode(node); // mHandler->FindDecl() will use/add entries to mNodeId2Decl TreeNode *decl = mHandler->FindDecl(node); @@ -607,11 +610,13 @@ bool TypeInferVisitor::UpdateVarTypeWithInit(TreeNode *var, TreeNode *init) { } } else if (init->IsIdentifier()) { TreeNode *decl = mHandler->FindDecl(static_cast(init)); - unsigned tidx = decl->GetTypeIdx(); - if (decl && (decl->IsClass() || (0 < tidx && tidx < (unsigned)TY_Max))) { - SetTypeId(idnode, TY_Function); - SetUpdated(); - result = true; + if (decl) { + unsigned tidx = decl->GetTypeIdx(); + if ((decl->IsClass() || (0 < tidx && tidx < (unsigned)TY_Max))) { + SetTypeId(idnode, TY_Function); + SetUpdated(); + result = true; + } } } else if (init->IsArrayLiteral()) { TypeId tid = GetArrayElemTypeId(init); @@ -970,7 +975,7 @@ CallNode *TypeInferVisitor::VisitCallNode(CallNode *node) { if (id->GetType()) { decl = id->GetType(); } else if (id->IsTypeIdFunction()) { - NOTYETIMPL("VisitCallNode nTY_Function"); + NOTYETIMPL("VisitCallNode TY_Function"); } } if (decl) { @@ -1390,6 +1395,9 @@ FunctionNode *TypeInferVisitor::VisitFunctionNode(FunctionNode *node) { IdentifierNode *TypeInferVisitor::VisitIdentifierNode(IdentifierNode *node) { if (mFlags & FLG_trace_1) std::cout << "Visiting IdentifierNode, id=" << node->GetNodeId() << "..." << std::endl; + if (mAstOpt->IsLangKeyword(node)) { + return node; + } TreeNode *type = node->GetType(); if (type) { if (type->IsPrimArrayType()) { diff --git a/src/MapleFE/astopt/src/astopt.cpp b/src/MapleFE/astopt/src/astopt.cpp index 8541ea171f..bd2ab47d29 100644 --- a/src/MapleFE/astopt/src/astopt.cpp +++ b/src/MapleFE/astopt/src/astopt.cpp @@ -56,7 +56,7 @@ void AstOpt::ProcessAST(unsigned flags) { } } - // build dependency of modules + // build dependency of modules PreprocessModules(); for (auto handler: mHandlersInOrder) { @@ -90,6 +90,11 @@ void AstOpt::PreprocessModules() { // initialize gTypeTable with builtin types gTypeTable.AddPrimAndBuiltinTypes(); + // collect language keywords +#undef LANGKEYWORD +#define LANGKEYWORD(K) mLangKeywords.insert(gStringPool.GetStrIdx(#K)); +#include "lang_keywords.def" + // scan through modules to setup mNodeId2NodeMap BuildNodeIdToNodeVisitor visitor(this, mFlags); diff --git a/src/MapleFE/java/include/lang_keywords.def b/src/MapleFE/java/include/lang_keywords.def new file mode 100644 index 0000000000..cc571c8c9d --- /dev/null +++ b/src/MapleFE/java/include/lang_keywords.def @@ -0,0 +1,71 @@ +// Copyright (C) [2021] Futurewei Technologies Inc. All rights reverved. +// +// OpenArkFE is licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// +// http://license.coscl.org.cn/MulanPSL2 +// +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS WITHOUT WARRANTIES OF ANY KIND, EITHER +// EXPRESS OR IMPLIED INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +// FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. +// + +LANGKEYWORD(boolean) +LANGKEYWORD(byte) +LANGKEYWORD(char) +LANGKEYWORD(class) +LANGKEYWORD(double) +LANGKEYWORD(enum) +LANGKEYWORD(float) +LANGKEYWORD(int) +LANGKEYWORD(interface) +LANGKEYWORD(long) +LANGKEYWORD(package) +LANGKEYWORD(short) +LANGKEYWORD(void) + +LANGKEYWORD(var) + +LANGKEYWORD(break) +LANGKEYWORD(case) +LANGKEYWORD(catch) +LANGKEYWORD(continue) +LANGKEYWORD(default) +LANGKEYWORD(do) +LANGKEYWORD(else) +LANGKEYWORD(finally) +LANGKEYWORD(for) +LANGKEYWORD(goto) +LANGKEYWORD(if) +LANGKEYWORD(return) +LANGKEYWORD(switch) +LANGKEYWORD(try) +LANGKEYWORD(while) + +LANGKEYWORD(abstract) +LANGKEYWORD(const) +LANGKEYWORD(volatile) + +LANGKEYWORD(assert) +LANGKEYWORD(new) + +LANGKEYWORD(instanceof) +LANGKEYWORD(extends) +LANGKEYWORD(implements) +LANGKEYWORD(import) +LANGKEYWORD(super) +LANGKEYWORD(synchronized) +// LANGKEYWORD(this) +LANGKEYWORD(throw) +LANGKEYWORD(throws) +LANGKEYWORD(transient) + +LANGKEYWORD(final) +LANGKEYWORD(native) +LANGKEYWORD(private) +LANGKEYWORD(protected) +LANGKEYWORD(public) +LANGKEYWORD(static) +LANGKEYWORD(strictfp) diff --git a/src/MapleFE/typescript/include/lang_keywords.def b/src/MapleFE/typescript/include/lang_keywords.def new file mode 100644 index 0000000000..76d3e2dd2a --- /dev/null +++ b/src/MapleFE/typescript/include/lang_keywords.def @@ -0,0 +1,101 @@ +// Copyright (C) [2021] Futurewei Technologies, Inc. All rights reverved. +// +// OpenArkFE is licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// +// http://license.coscl.org.cn/MulanPSL2 +// +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +// FIT FOR A PARTICULAR PURPOSE. +// See the Mulan PSL v2 for more details. +// + +LANGKEYWORD(boolean) +LANGKEYWORD(number) +LANGKEYWORD(string) +LANGKEYWORD(symbol) +LANGKEYWORD(unique) +LANGKEYWORD(any) +LANGKEYWORD(unknown) +LANGKEYWORD(never) +LANGKEYWORD(undefined) +LANGKEYWORD(type) + +LANGKEYWORD(get) +LANGKEYWORD(set) +LANGKEYWORD(as) +LANGKEYWORD(from) +LANGKEYWORD(constructor) +LANGKEYWORD(namespace) +LANGKEYWORD(module) +LANGKEYWORD(declare) + +LANGKEYWORD(break) +LANGKEYWORD(do) +LANGKEYWORD(in) +LANGKEYWORD(is) +LANGKEYWORD(of) +LANGKEYWORD(typeof) +LANGKEYWORD(keyof) +LANGKEYWORD(infer) +LANGKEYWORD(case) +LANGKEYWORD(else) +LANGKEYWORD(instanceof) +LANGKEYWORD(var) +LANGKEYWORD(catch) +LANGKEYWORD(export) +LANGKEYWORD(new) +LANGKEYWORD(void) +LANGKEYWORD(class) +LANGKEYWORD(extends) +LANGKEYWORD(return) +LANGKEYWORD(while) +LANGKEYWORD(const) +LANGKEYWORD(finally) +LANGKEYWORD(super) +LANGKEYWORD(with) +LANGKEYWORD(continue) +LANGKEYWORD(for) +LANGKEYWORD(switch) +LANGKEYWORD(yield) +LANGKEYWORD(debugger) +LANGKEYWORD(function) +// LANGKEYWORD(this) +LANGKEYWORD(default) +LANGKEYWORD(if) +LANGKEYWORD(throw) +LANGKEYWORD(delete) +LANGKEYWORD(import) +LANGKEYWORD(require) +LANGKEYWORD(try) +LANGKEYWORD(asserts) + +LANGKEYWORD(let) +LANGKEYWORD(static) +LANGKEYWORD(implements) +LANGKEYWORD(protected) +LANGKEYWORD(interface) +LANGKEYWORD(private) +LANGKEYWORD(public) +LANGKEYWORD(abstract) + +LANGKEYWORD(readonly) + +LANGKEYWORD(enum) +LANGKEYWORD(await) +LANGKEYWORD(async) + +LANGKEYWORD(global) + +// extra + +LANGKEYWORD(console) +LANGKEYWORD(log) + +LANGKEYWORD(null) + +LANGKEYWORD(Parameters) +LANGKEYWORD(Error) +LANGKEYWORD(NonNullable) -- Gitee