diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 6f8dbb58986ae8b6d5bc1d09b18e74fd118afbe6..6d25361c19dc4d551c594df1bed017e672b02090 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -306,6 +306,7 @@ libes2panda_sources = [ "ir/brokenTypeNode.cpp", "ir/ets/etsClassLiteral.cpp", "ir/ets/etsFunctionType.cpp", + "ir/ets/etsIntrinsicNode.cpp", "ir/ets/etsKeyofType.cpp", "ir/ets/etsModule.cpp", "ir/ets/etsNeverType.cpp", @@ -541,6 +542,7 @@ HEADERS_TO_BE_PARSED = [ "ir/statement.h", "ir/irnode.h", "checker/types/typeRelation.h", + "ir/ets/etsIntrinsicNode.h", "ir/visitor/AstVisitor.h", "ir/statements/classDeclaration.h", "ir/base/tsMethodSignature.h", @@ -819,6 +821,7 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/ir/visitor/IterateAstVisitor.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/functionDeclaration.yaml", "$LIBGEN_DIR/gen/headers/ir/ets/etsTypeReference.yaml", + "$LIBGEN_DIR/gen/headers/ir/ets/etsIntrinsicNode.yaml", "$LIBGEN_DIR/gen/headers/checker/types/ts/tupleType.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsTypeReference.yaml", "$LIBGEN_DIR/gen/headers/checker/types/ts/functionType.yaml", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index ca1b8beaaf6110a89ee78c455437f8cafb8435cc..c53de4f112e45f0351dce801e28a98b12ca78b1c 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -429,6 +429,7 @@ set(ES2PANDA_LIB_SRC ir/as/namedType.cpp ir/as/prefixAssertionExpression.cpp ir/ets/etsClassLiteral.cpp + ir/ets/etsIntrinsicNode.cpp ir/ets/etsFunctionType.cpp ir/ets/etsKeyofType.cpp ir/ets/etsNewArrayInstanceExpression.cpp diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 47e0797c65d9b1f4d5ea63ba08e3dac705a93c21..951f2217220594c4f069a014cf96b7d906716a2c 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2768,6 +2768,25 @@ checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const return expr->TsType(); } +checker::Type *ETSAnalyzer::Check(ir::ETSIntrinsicNode *node) const +{ + ETSChecker *checker = GetETSChecker(); + for (auto *arg : node->Arguments()) { + arg->Check(checker); + } + // Note (daizihan): #27074, make it more scalable when IntrinsicNodeType is extended. + if (node->Type() == ir::IntrinsicNodeType::TYPE_REFERENCE) { + auto type = checker->GlobalBuiltinClassType()->Clone(checker); + // Since std.core.Class initialize() is instance method, need to remove the variable flag. + auto newVar = type->Variable()->AsLocalVariable()->Copy(checker->Allocator(), type->Variable()->Declaration()); + newVar->RemoveFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE); + type->SetVariable(newVar); + return node->SetTsType(type); + } + ES2PANDA_UNREACHABLE(); + return checker->GlobalTypeError(); +} + checker::Type *ETSAnalyzer::Check(ir::ImportDeclaration *st) const { ETSChecker *checker = GetETSChecker(); diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 8b45002d11ce2090812b5780127b9d7b276368c4..bfc1b88c8f1c5c50757527a4ee7013cf46d29cb6 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -585,6 +585,11 @@ ETSUnionType *ETSChecker::GlobalETSUnionUndefinedNullObject() const return ret != nullptr ? ret->AsETSUnionType() : nullptr; } +ETSObjectType *ETSChecker::GlobalBuiltinClassType() const +{ + return AsETSObjectType(&GlobalTypesHolder::GlobalClassBuiltinType); +} + ETSObjectType *ETSChecker::GlobalBuiltinETSResizableArrayType() const { return AsETSObjectType(&GlobalTypesHolder::GlobalArrayBuiltinType); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 4da77afe91abb1e111c8789d6798e9f810c7a0dd..a66869952a032aa4c82a6842183a2380d856b160 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -150,6 +150,7 @@ public: ETSObjectType *GlobalETSObjectType() const; ETSUnionType *GlobalETSUnionUndefinedNull() const; ETSUnionType *GlobalETSUnionUndefinedNullObject() const; + ETSObjectType *GlobalBuiltinClassType() const; ETSObjectType *GlobalBuiltinETSResizableArrayType() const; ETSObjectType *GlobalBuiltinETSStringType() const; ETSObjectType *GlobalBuiltinETSBigIntType() const; diff --git a/ets2panda/checker/SemanticAnalyzer.h b/ets2panda/checker/SemanticAnalyzer.h index b0db804c0861695bd2c965bb20e8f232feabd08c..db3d9007a874b3f7b81571f715567a741c55f59f 100644 --- a/ets2panda/checker/SemanticAnalyzer.h +++ b/ets2panda/checker/SemanticAnalyzer.h @@ -37,6 +37,7 @@ #include "ir/base/tsSignatureDeclaration.h" #include "ir/ets/etsClassLiteral.h" #include "ir/ets/etsFunctionType.h" +#include "ir/ets/etsIntrinsicNode.h" #include "ir/ets/etsImportDeclaration.h" #include "ir/ets/etsKeyofType.h" #include "ir/ets/etsNewArrayInstanceExpression.h" diff --git a/ets2panda/checker/TSAnalyzerUnreachable.cpp b/ets2panda/checker/TSAnalyzerUnreachable.cpp index e5c22b6907deb5347cbd8553504c68ee31ae8b77..8b0a749ef1dead37cebdd54ffd91222be289427b 100644 --- a/ets2panda/checker/TSAnalyzerUnreachable.cpp +++ b/ets2panda/checker/TSAnalyzerUnreachable.cpp @@ -84,6 +84,11 @@ checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSFunctionType *node) con ES2PANDA_UNREACHABLE(); } +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSIntrinsicNode *node) const +{ + ES2PANDA_UNREACHABLE(); +} + checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSImportDeclaration *node) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index effd56d037a21930e60f7d6bdbf11975003d90a5..1a3dd612203487fdf9636bb105b19026846b5efa 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -160,6 +160,7 @@ void GlobalTypesHolder::AddEtsSpecificBuiltinTypes() builtinNameMappings_.emplace("Boolean", GlobalTypeId::ETS_BOOLEAN_BUILTIN); builtinNameMappings_.emplace("Byte", GlobalTypeId::ETS_BYTE_BUILTIN); builtinNameMappings_.emplace("Char", GlobalTypeId::ETS_CHAR_BUILTIN); + builtinNameMappings_.emplace("Class", GlobalTypeId::ETS_CLASS_BUILTIN); builtinNameMappings_.emplace("Comparable", GlobalTypeId::ETS_COMPARABLE_BUILTIN); builtinNameMappings_.emplace("Console", GlobalTypeId::ETS_CONSOLE_BUILTIN); builtinNameMappings_.emplace("Double", GlobalTypeId::ETS_DOUBLE_BUILTIN); @@ -448,6 +449,11 @@ Type *GlobalTypesHolder::GlobalByteBuiltinType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_BYTE_BUILTIN)); } +Type *GlobalTypesHolder::GlobalClassBuiltinType() +{ + return globalTypes_.at(static_cast(GlobalTypeId::ETS_CLASS_BUILTIN)); +} + Type *GlobalTypesHolder::GlobalCharBuiltinType() { return globalTypes_.at(static_cast(GlobalTypeId::ETS_CHAR_BUILTIN)); diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index 1818385b6ce347ae9e5e3432498a13d974a5a10b..16d39147b08f7c7280db47bf3362ccff000bba4b 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -65,6 +65,7 @@ enum class GlobalTypeId : std::size_t { ETS_WILDCARD, ETS_BOOLEAN_BUILTIN, ETS_BYTE_BUILTIN, + ETS_CLASS_BUILTIN, ETS_CHAR_BUILTIN, ETS_COMPARABLE_BUILTIN, ETS_CONSOLE_BUILTIN, @@ -278,6 +279,7 @@ public: Type *GlobalWildcardType(); Type *GlobalETSBooleanBuiltinType(); Type *GlobalByteBuiltinType(); + Type *GlobalClassBuiltinType(); Type *GlobalCharBuiltinType(); Type *GlobalComparableBuiltinType(); Type *GlobalConsoleBuiltinType(); diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index a0159934396bc21a3d0f4721db1ee221abf28276..798ec10abff49a3d9d3c353f566e61936261fce9 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -998,6 +998,19 @@ bool ETSCompiler::HandleStaticProperties(const ir::MemberExpression *expr, ETSGe return false; } +void ETSCompiler::Compile(const ir::ETSIntrinsicNode *expr) const +{ + ETSGen *etsg = GetETSGen(); + // Note (daizihan): #27074, make it more scalable when IntrinsicNodeType is extended. + if (expr->Type() == ir::IntrinsicNodeType::TYPE_REFERENCE) { + // Note (daizihan): #27086, we should not use stringLiteral as argument in ETSIntrinsicNode, should be TypeNode. + etsg->EmitLdaType(expr, expr->Arguments()[0]->AsStringLiteral()->Str()); + etsg->SetAccumulatorType(expr->TsType()); + return; + } + ES2PANDA_UNREACHABLE(); +} + void ETSCompiler::Compile(const ir::ObjectExpression *expr) const { ETSGen *etsg = GetETSGen(); diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 084e2edfa2f48d1e6bf6ee935a29bd2add62d5c8..6707dcca73a6e12333960659e066c0a7727448d2 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -461,6 +461,11 @@ public: } } + void EmitLdaType(const ir::AstNode *node, util::StringView sv) + { + Sa().Emit(node, sv); + } + ~ETSGen() override = default; NO_COPY_SEMANTIC(ETSGen); NO_MOVE_SEMANTIC(ETSGen); diff --git a/ets2panda/compiler/core/JSCompilerUnreachable.cpp b/ets2panda/compiler/core/JSCompilerUnreachable.cpp index 391a89c24c7cc9e14133b83acee5f7761b91fb82..8a4b29a9a5381546c96d1985622c046425e55750 100644 --- a/ets2panda/compiler/core/JSCompilerUnreachable.cpp +++ b/ets2panda/compiler/core/JSCompilerUnreachable.cpp @@ -98,6 +98,11 @@ void JSCompiler::Compile([[maybe_unused]] const ir::ETSClassLiteral *expr) const ES2PANDA_UNREACHABLE(); } +void JSCompiler::Compile([[maybe_unused]] const ir::ETSIntrinsicNode *expr) const +{ + ES2PANDA_UNREACHABLE(); +} + void JSCompiler::Compile([[maybe_unused]] const ir::ETSFunctionType *expr) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index b9f60c91ac7dba6d37bd54eb5bb1f24dedcb7d56..1c8de1aad78927c21d52d631353a8235ff6e2cf0 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -17,18 +17,20 @@ #include #include "compiler/lowering/util.h" -#include "ir/statements/classDeclaration.h" #include "ir/base/classDefinition.h" #include "ir/base/classProperty.h" #include "ir/base/classStaticBlock.h" #include "ir/base/scriptFunction.h" #include "ir/base/methodDefinition.h" +#include "ir/ets/etsIntrinsicNode.h" +#include "ir/expressions/memberExpression.h" #include "ir/expressions/identifier.h" #include "ir/expressions/classExpression.h" #include "ir/expressions/functionExpression.h" #include "ir/expressions/callExpression.h" -#include "ir/statements/expressionStatement.h" #include "ir/statements/blockStatement.h" +#include "ir/statements/classDeclaration.h" +#include "ir/statements/expressionStatement.h" #include "util/helpers.h" #include "util/ustring.h" #include "utils/arena_containers.h" @@ -295,7 +297,8 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns) initializerBlock.emplace_back(GlobalStmts {globalProgram_, std::move(initBlock)}); } AddStaticBlockToClass(globalClass); - const ModuleDependencies md {allocator_->Adapter()}; + const ModuleDependencies md(ArenaVector(allocator_->Adapter()), + ArenaUnorderedSet(allocator_->Adapter())); auto immediateInitStatements = FormInitMethodStatements(&md, std::move(immediateInitializers)); auto initializerBlockStatements = FormInitStaticBlockMethodStatements(&md, std::move(initializerBlock)); SetupGlobalMethods(std::move(immediateInitStatements), globalClass, ns->IsDeclare()); @@ -515,11 +518,27 @@ ArenaVector GlobalClassHandler::FormInitMethodStatements(const return statements; } -void GlobalClassHandler::FormDependentInitTriggers([[maybe_unused]] ArenaVector &statements, - [[maybe_unused]] const ModuleDependencies *moduleDependencies) +void GlobalClassHandler::FormDependentInitTriggers(ArenaVector &statements, + const ModuleDependencies *moduleDependencies) { - // NOTE(dslynko, #26183): leaving this function for later reuse in `import "path"` feature, - // which would initialize the dependency. + for (const auto module : moduleDependencies->first) { + ArenaVector params(allocator_->Adapter()); + auto moduleStr = util::UString { + module->ModuleInfo().modulePrefix.Mutf8().append(compiler::Signatures::ETS_GLOBAL), allocator_}; + auto moduleName = NodeAllocator::Alloc(allocator_, moduleStr.View()); + params.emplace_back(moduleName); + // Note (daizihan): #27086, we should not use stringLiteral as argument in ETSIntrinsicNode, should be TypeNode. + auto moduleNode = NodeAllocator::Alloc(allocator_, ir::IntrinsicNodeType::TYPE_REFERENCE, + std::move(params)); + auto initIdent = + NodeAllocator::Alloc(allocator_, compiler::Signatures::CLASS_INITIALIZE_METHOD, allocator_); + auto *callee = NodeAllocator::Alloc( + allocator_, moduleNode, initIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *const callExpr = NodeAllocator::Alloc( + allocator_, callee, ArenaVector(allocator_->Adapter()), nullptr, false, false); + auto stmt = NodeAllocator::Alloc(allocator_, callExpr); + statements.emplace_back(stmt); + } } ir::ClassStaticBlock *GlobalClassHandler::CreateStaticBlock(ir::ClassDefinition *classDef) diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h index 542f132c090743901d40396d17ec10d56cea4f96..79bfdd1b94049d8f420f6344f494a7955c374ec8 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h @@ -26,7 +26,8 @@ namespace ark::es2panda::compiler { class GlobalClassHandler { public: - using ModuleDependencies = ArenaUnorderedSet; + // Using ArenaVector to ensure the order of the module dependencies; + using ModuleDependencies = std::pair, ArenaUnorderedSet>; struct GlobalStmts { parser::Program *program; @@ -54,6 +55,15 @@ public: globalProgram_ = program; } + static void InsertModuleDependencies(ModuleDependencies *moduleDependencies, parser::Program *program) + { + if (moduleDependencies->second.find(program) != moduleDependencies->second.end()) { + return; + } + moduleDependencies->first.emplace_back(program); + moduleDependencies->second.insert(program); + } + private: /** * Move top level statements to _$init$_ and @@ -75,6 +85,7 @@ private: bool isDeclare); void SetupInitializerBlock(ArenaVector> &&initializerBlock, ir::ClassDefinition *globalClass); + void SetupInitializationMethodIfNeeded(ir::ClassDefinition *classDef); ArenaVector TransformNamespaces(ArenaVector &namespaces); ir::ClassDeclaration *CreateGlobalClass(const parser::Program *globalProgram); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp index dc8869fffa872ddab6fbd2b0acda0100c0a107b5..1560a75375ffcf5ed631d03da4d1537bbb5c7b8d 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp @@ -36,6 +36,18 @@ GlobalDeclTransformer::ResultT GlobalDeclTransformer::TransformStatements(const return std::move(result_); } +void GlobalDeclTransformer::VisitExpressionStatement(ir::ExpressionStatement *exprStmt) +{ + if (exprStmt->GetExpression()->IsCallExpression()) { + auto *callExpr = exprStmt->GetExpression()->AsCallExpression(); + if (callExpr->Callee()->IsIdentifier() && + callExpr->Callee()->AsIdentifier()->Name() == compiler::Signatures::INIT_MODULE_METHOD) { + return; // skip initModule call + } + } + result_.immediateInit.emplace_back(exprStmt); +} + void GlobalDeclTransformer::VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) { auto *funcExpr = util::NodeAllocator::ForceSetParent(allocator_, funcDecl->Function()); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.h b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.h index 8e38b224e18e67486e67794ea62a3d1f2d22da6c..eada14a27c95a0876a26f2b098689b85203949e5 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.h @@ -82,6 +82,7 @@ public: void VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) override; void VisitVariableDeclaration(ir::VariableDeclaration *varDecl) override; void VisitClassStaticBlock(ir::ClassStaticBlock *classStaticBlock) override; + void VisitExpressionStatement(ir::ExpressionStatement *exprStmt) override; void HandleNode(ir::AstNode *node) override; bool CheckValidInitializer(ir::AstNode const *initializer) const; diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp index fd25d833a5663af3292bf7752b304ae7531253a6..f173d3fa47171eab38b10fc0edff466b044f351e 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp @@ -14,6 +14,8 @@ */ #include "compiler/lowering/ets/topLevelStmts/importExportDecls.h" +#include "compiler/lowering/util.h" +#include "utils/arena_containers.h" namespace ark::es2panda::compiler { @@ -28,6 +30,24 @@ void ImportExportDecls::ParseDefaultSources() varbinder_->SetDefaultImports(std::move(imports)); } +void ImportExportDecls::HandleInitModuleCallExpression(ir::CallExpression *callExpr, parser::Program *program, + GlobalClassHandler::ModuleDependencies &moduleDependencies) +{ + if (!callExpr->Callee()->IsIdentifier() || + callExpr->Callee()->AsIdentifier()->Name() != compiler::Signatures::INIT_MODULE_METHOD) { + return; + } + + auto metaData = parser_->GetImportPathManager()->GatherImportMetadata( + program, util::ImportFlags::NONE, callExpr->Arguments().front()->AsStringLiteral()); + + bool isSimultaneous = ctx_->config->options->GetCompilationMode() == CompilationMode::GEN_ABC_FOR_EXTERNAL_SOURCE; + auto sources = isSimultaneous ? ctx_->parserProgram->ExternalSources() : program->DirectExternalSources(); + if (auto dependentProg = SearchExternalProgramInImport(sources, metaData); dependentProg != nullptr) { + GlobalClassHandler::InsertModuleDependencies(&moduleDependencies, dependentProg); + } +} + void ImportExportDecls::ProcessProgramStatements(parser::Program *program, const ArenaVector &statements, GlobalClassHandler::ModuleDependencies &moduleDependencies) @@ -46,6 +66,10 @@ void ImportExportDecls::ProcessProgramStatements(parser::Program *program, if (stmt->IsTSTypeAliasDeclaration() && (stmt->IsExported() || stmt->IsDefaultExported())) { PopulateAliasMap(stmt->AsTSTypeAliasDeclaration(), program->SourceFilePath()); } + if (stmt->IsExpressionStatement() && stmt->AsExpressionStatement()->GetExpression()->IsCallExpression()) { + HandleInitModuleCallExpression(stmt->AsExpressionStatement()->GetExpression()->AsCallExpression(), program, + moduleDependencies); + } } } @@ -53,7 +77,9 @@ GlobalClassHandler::ModuleDependencies ImportExportDecls::HandleGlobalStmts(Aren { VerifySingleExportDefault(programs); VerifyTypeExports(programs); - GlobalClassHandler::ModuleDependencies moduleDependencies {programs.front()->Allocator()->Adapter()}; + GlobalClassHandler::ModuleDependencies moduleDependencies( + ArenaVector(programs.front()->Allocator()->Adapter()), + ArenaUnorderedSet(programs.front()->Allocator()->Adapter())); if (!programs.empty()) { std::sort(programs.begin(), programs.end(), ProgramFileNameLessThan); } diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h index f5b04f3f5bdb3829b58e741b6bb66fd7516326ef..c6c8f763145cfcfc44640ef9ac30267550edfc64 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h @@ -41,8 +41,8 @@ class ImportExportDecls : ir::visitor::EmptyAstVisitor { public: ImportExportDecls() = default; - ImportExportDecls(varbinder::ETSBinder *varbinder, parser::ETSParser *parser) - : varbinder_(varbinder), parser_(parser) + ImportExportDecls(varbinder::ETSBinder *varbinder, parser::ETSParser *parser, public_lib::Context *ctx) + : varbinder_(varbinder), parser_(parser), ctx_(ctx) { } @@ -84,6 +84,8 @@ private: void VisitETSImportDeclaration(ir::ETSImportDeclaration *importDecl) override; void VisitAnnotationDeclaration(ir::AnnotationDeclaration *annotationDecl) override; void VisitETSModule(ir::ETSModule *etsModule) override; + void HandleInitModuleCallExpression(ir::CallExpression *expr, parser::Program *program, + GlobalClassHandler::ModuleDependencies &moduleDependencies); private: varbinder::ETSBinder *varbinder_ {nullptr}; @@ -91,6 +93,7 @@ private: std::map exportNameMap_; std::set exportedTypes_; parser::ETSParser *parser_ {nullptr}; + public_lib::Context *ctx_ {nullptr}; std::map importedSpecifiersForExportCheck_; lexer::SourcePosition lastExportErrorPos_ {}; util::StringView exportDefaultName_; diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp index 474b8f705eb025350e2939106e206ac5c44f500d..3bb6b09ea2b44d407195a581e4abcb53f6b4785a 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp @@ -95,7 +95,7 @@ static void CheckFileHeaderFlag(parser::Program *program) bool TopLevelStatements::Perform(public_lib::Context *ctx, parser::Program *program) { CheckFileHeaderFlag(program); - auto imports = ImportExportDecls(program->VarBinder()->AsETSBinder(), ctx->parser->AsETSParser()); + auto imports = ImportExportDecls(program->VarBinder()->AsETSBinder(), ctx->parser->AsETSParser(), ctx); imports.ParseDefaultSources(); if (!CheckProgramSourcesConsistency(program)) { // NOTE(vpukhov): enforce compilation failure diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index a4c4e1336a99c85f07a286b5c5d047885ba99b37..a175fe9007f5c8c8a4c747efa0d1fcacfc8cf20d 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -377,6 +377,23 @@ void CheckLoweredNode(varbinder::ETSBinder *varBinder, checker::ETSChecker *chec node->Check(checker); } +parser::Program *SearchExternalProgramInImport(const parser::Program::DirectExternalSource &extSource, + const util::ImportPathManager::ImportMetadata &importMetadata) +{ + parser::Program *extProg = nullptr; + const auto importPath = importMetadata.resolvedSource; + // Search Correct external program by comparing importPath and absolutePath + for (auto &[_, progs] : extSource) { + auto it = std::find_if(progs.begin(), progs.end(), + [&](const auto *prog) { return prog->AbsoluteName() == importPath; }); + if (it != progs.end()) { + extProg = *it; + break; + } + } + return extProg; +} + bool IsAnonymousClassType(const checker::Type *type) { if (type == nullptr || !type->IsETSObjectType()) { diff --git a/ets2panda/compiler/lowering/util.h b/ets2panda/compiler/lowering/util.h index a5b8db5b373e00931834200a2d01c3b10bfef686..8f5202f4aa7d77287ecfdb1a4b06592f0c83a756 100644 --- a/ets2panda/compiler/lowering/util.h +++ b/ets2panda/compiler/lowering/util.h @@ -17,6 +17,7 @@ #define ES2PANDA_COMPILER_LOWERING_UTIL_H #include "varbinder/ETSBinder.h" +#include "parser/program/program.h" namespace ark::es2panda::compiler { @@ -51,6 +52,9 @@ void BindLoweredNode(varbinder::ETSBinder *varBinder, ir::AstNode *node); // Note: run varbinder and checker on the new node generated in lowering phases void CheckLoweredNode(varbinder::ETSBinder *varBinder, checker::ETSChecker *checker, ir::AstNode *node); +parser::Program *SearchExternalProgramInImport(const parser::Program::DirectExternalSource &extSource, + const util::ImportPathManager::ImportMetadata &importMetadata); + bool IsAnonymousClassType(const checker::Type *type); bool ClassDefinitionIsEnumTransformed(const ir::AstNode *node); } // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 5366d99f389d7165f0996561b1725f1b8ed844e1..5f9646534678b9f085e3d17ddab6c2f098549e2d 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -24,6 +24,8 @@ defines: ref: INIT_METHOD - name: _$initializerBlockInit$_ ref: INITIALIZER_BLOCK_INIT + - name: initModule + ref: INIT_MODULE_METHOD - name: $_get ref: GET_INDEX_METHOD - name: $_set @@ -244,6 +246,8 @@ defines: ref: UNUSED_ETSGLOBAL_INIT - name: 'ETSGLOBAL.main:void;' ref: UNUSED_ETSGLOBAL_MAIN + - name: "initialize" + ref: CLASS_INITIALIZE_METHOD packages: - name: 'std.core' diff --git a/ets2panda/ir/astNodeMapping.h b/ets2panda/ir/astNodeMapping.h index 0c2e397721317dab25bef5e7e2c3592c39576f64..06ece5eff06235af7eff5fdb7877affefed6146b 100644 --- a/ets2panda/ir/astNodeMapping.h +++ b/ets2panda/ir/astNodeMapping.h @@ -86,6 +86,7 @@ _(ETS_UNDEFINED_TYPE, ETSUndefinedType) \ _(ETS_NEVER_TYPE, ETSNeverType) \ _(ETS_STRING_LITERAL_TYPE, ETSStringLiteralType) \ + _(ETS_INTRINSIC_NODE_TYPE, ETSIntrinsicNode) \ _(ETS_FUNCTION_TYPE, ETSFunctionType) \ _(ETS_WILDCARD_TYPE, ETSWildcardType) \ _(ETS_PRIMITIVE_TYPE, ETSPrimitiveType) \ diff --git a/ets2panda/ir/ets/etsIntrinsicNode.cpp b/ets2panda/ir/ets/etsIntrinsicNode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e542459c289d5041931c72b88d28857ff9e8a7c --- /dev/null +++ b/ets2panda/ir/ets/etsIntrinsicNode.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025 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. + */ + +#include "etsIntrinsicNode.h" + +#include "checker/ETSchecker.h" +#include "compiler/core/ETSGen.h" + +namespace ark::es2panda::ir { + +ETSIntrinsicNode::ETSIntrinsicNode(ETSIntrinsicNode const &other, ArenaAllocator *const allocator) + : Expression(static_cast(other)), arguments_(allocator->Adapter()) +{ + type_ = other.type_; + for (auto *const arg : other.arguments_) { + arguments_.emplace_back(arg->Clone(allocator, this)->AsExpression()); + } +} + +void ETSIntrinsicNode::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) +{ + for (auto *&args : arguments_) { + if (auto *transformedNode = cb(args); args != transformedNode) { + args->SetTransformedNode(transformationName, transformedNode); + args = static_cast(transformedNode); + } + } +} + +void ETSIntrinsicNode::Iterate(const NodeTraverser &cb) const +{ + for (auto *arg : arguments_) { + cb(arg); + } +} + +void ETSIntrinsicNode::Dump(ir::AstDumper *dumper) const +{ + dumper->Add({{"type", "ETSIntrinsicNode"}, {"arguments", arguments_}}); +} + +void ETSIntrinsicNode::Dump([[maybe_unused]] ir::SrcDumper *dumper) const +{ + // Note (daizihan): #27074, make it more scalable when IntrinsicNodeType is extended. + if (type_ == IntrinsicNodeType::TYPE_REFERENCE) { + dumper->Add("__intrin_type_reference("); + for (auto arg : arguments_) { + arg->Dump(dumper); + if (arg != arguments_.back()) { + dumper->Add(", "); + } + } + dumper->Add(")"); + } +} + +void ETSIntrinsicNode::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} + +void ETSIntrinsicNode::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} + +checker::Type *ETSIntrinsicNode::Check([[maybe_unused]] checker::TSChecker *checker) +{ + return nullptr; +} + +checker::VerifiedType ETSIntrinsicNode::Check([[maybe_unused]] checker::ETSChecker *checker) +{ + return {this, checker->GetAnalyzer()->Check(this)}; +} + +ETSIntrinsicNode *ETSIntrinsicNode::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + ETSIntrinsicNode *clone = allocator->New(allocator); + clone->type_ = type_; + if (parent != nullptr) { + clone->SetParent(parent); + } + clone->SetRange(Range()); + return clone; +} +} // namespace ark::es2panda::ir \ No newline at end of file diff --git a/ets2panda/ir/ets/etsIntrinsicNode.h b/ets2panda/ir/ets/etsIntrinsicNode.h new file mode 100644 index 0000000000000000000000000000000000000000..d13a914c2fbe7bf6d0ad0eb32654209ce27846dc --- /dev/null +++ b/ets2panda/ir/ets/etsIntrinsicNode.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2025 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. + */ + +#ifndef ES2PANDA_IR_ETS_INTRINSIC_NODE_H +#define ES2PANDA_IR_ETS_INTRINSIC_NODE_H + +#include "ir/expression.h" +#include "ir/visitor/AstVisitor.h" +#include "utils/arena_containers.h" + +namespace ark::es2panda::ir { + +enum class IntrinsicNodeType : uint8_t { NONE = 0, TYPE_REFERENCE = 1 }; + +class ETSIntrinsicNode : public Expression { +public: + ETSIntrinsicNode() = delete; + ~ETSIntrinsicNode() override = default; + + NO_COPY_SEMANTIC(ETSIntrinsicNode); + NO_MOVE_SEMANTIC(ETSIntrinsicNode); + + explicit ETSIntrinsicNode(ArenaAllocator *const allocator) + : Expression(AstNodeType::ETS_INTRINSIC_NODE_TYPE), + type_(IntrinsicNodeType::NONE), + arguments_(allocator->Adapter()) + { + } + + explicit ETSIntrinsicNode(ETSIntrinsicNode const &other, ArenaAllocator *const allocator); + + explicit ETSIntrinsicNode(IntrinsicNodeType type, ArenaVector &&arguments) + : Expression(AstNodeType::ETS_INTRINSIC_NODE_TYPE), type_(type), arguments_(std::move(arguments)) + { + } + + IntrinsicNodeType Type() const + { + return type_; + } + + ArenaVector Arguments() const + { + return arguments_; + } + + void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; + void Iterate(const NodeTraverser &cb) const override; + void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; + void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; + checker::VerifiedType Check([[maybe_unused]] checker::ETSChecker *checker) override; + + void Accept(ASTVisitorT *v) override + { + v->Accept(this); + } + + [[nodiscard]] ETSIntrinsicNode *Clone(ArenaAllocator *allocator, AstNode *parent) override; + +private: + IntrinsicNodeType type_; + ArenaVector arguments_; +}; +} // namespace ark::es2panda::ir + +#endif \ No newline at end of file diff --git a/ets2panda/ir/visitor/IterateAstVisitor.h b/ets2panda/ir/visitor/IterateAstVisitor.h index 5b185634598696b995e7e7fa49bbdf4912b5cd69..79274780e6f1b6c15cf870658ff22aef2dad83fd 100644 --- a/ets2panda/ir/visitor/IterateAstVisitor.h +++ b/ets2panda/ir/visitor/IterateAstVisitor.h @@ -20,6 +20,7 @@ #include "ir/brokenTypeNode.h" #include "ir/expressions/literals/undefinedLiteral.h" #include "ir/expressions/blockExpression.h" +#include "ir/ets/etsIntrinsicNode.h" #include "ir/ets/etsUnionType.h" #include "ir/ets/etsStringLiteralType.h" #include "ir/ets/etsTuple.h" diff --git a/ets2panda/lexer/scripts/keywords.yaml b/ets2panda/lexer/scripts/keywords.yaml index 3ed7f5ff79b968f79653accfe1985b6313fa2988..3b03c20867e7301bb15df09742a9fe9773172e43 100644 --- a/ets2panda/lexer/scripts/keywords.yaml +++ b/ets2panda/lexer/scripts/keywords.yaml @@ -305,6 +305,11 @@ keywords: token: KEYW_INFER keyword_like: [ts] + - name: 'initModule' + token: KEYW_INIT_MODULE + keyword_like: [ets] + flags: [reserved_type_name] + - name: 'instanceof' token: KEYW_INSTANCEOF keyword: [as, js, ts] diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index fff197fa753476379ecbecae8049ce8b4fe94b6d..3aae7a2ec971e216fc413454e23d7175c6610f8a 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -171,6 +171,9 @@ ir::ETSModule *ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, A auto imports = ParseImportDeclarations(); statements.insert(statements.end(), imports.begin(), imports.end()); + auto initModules = ParseETSInitModuleStatements(); + statements.insert(statements.end(), initModules.begin(), initModules.end()); + auto topLevelStatements = ParseTopLevelDeclaration(); statements.insert(statements.end(), topLevelStatements.begin(), topLevelStatements.end()); @@ -1233,6 +1236,16 @@ lexer::LexerPosition ETSParser::HandleJsDocLikeComments() return savedPos; } +ArenaVector ETSParser::ParseETSInitModuleStatements() +{ + std::vector userPaths; + ArenaVector statements(Allocator()->Adapter()); + while (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_INIT_MODULE) { + statements.push_back(ParseInitModuleStatement(StatementParsingFlags::INIT_MODULE)); + } + return statements; +} + ArenaVector ETSParser::ParseImportDeclarations() { auto savedPos = HandleJsDocLikeComments(); diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 250f09b7cee0f575415962a1c3e26f435d725ce3..b6dde94c50b41e9e294bf5c55ec2039c6de66a78 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -204,6 +204,7 @@ private: ir::ExportNamedDeclaration *ParseSingleExport(ir::ModifierFlags modifiers); ir::ExportNamedDeclaration *ParseSingleExportForAnonymousConst(ir::ModifierFlags modifiers); ArenaVector ParseImportDeclarations(); + ArenaVector ParseETSInitModuleStatements(); ir::Statement *ParseImportDeclarationHelper(lexer::SourcePosition startLoc, ArenaVector &specifiers, ir::ImportKinds importKind); bool TryMergeFromCache(size_t idx, ArenaVector &parseList); @@ -298,6 +299,7 @@ private: ir::Statement *ParseExportDeclaration(StatementParsingFlags flags) override; ir::AnnotatedExpression *ParseVariableDeclaratorKey(VariableParsingFlags flags) override; ir::Statement *ParseAnnotationsInStatement(StatementParsingFlags flags) override; + ir::Statement *ParseInitModuleStatement(StatementParsingFlags flags) override; ir::VariableDeclarator *ParseVariableDeclarator(ir::Expression *init, lexer::SourcePosition startLoc, VariableParsingFlags flags) override; ir::VariableDeclarator *ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags, diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index 3a3bcf9294d53d5659622ed6731eaba11bc2beb7..f59b4794d5db9184349ad18c264083e930ce621c 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -20,6 +20,7 @@ #include "parser/parserFlags.h" #include "util/errorRecovery.h" #include "util/helpers.h" +#include "util/importPathManager.h" #include "utils/arena_containers.h" #include "varbinder/varbinder.h" #include "varbinder/ETSBinder.h" @@ -258,6 +259,32 @@ ir::Statement *ETSParser::ParseTopLevelStatement() return result; } +ir::Statement *ETSParser::ParseInitModuleStatement(StatementParsingFlags flags) +{ + auto startLoc = Lexer()->GetToken().Start(); + if ((flags & StatementParsingFlags::INIT_MODULE) == 0) { + LogError(diagnostic::INIT_MODULE_DECLARATION_POSITION); + return AllocBrokenStatement(startLoc); + } + + auto *callee = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + Lexer()->NextToken(); // eat initModule + if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { + LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); + return AllocBrokenStatement(startLoc); + } + ir::CallExpression *expr = ParseCallExpression(callee, false, false); + expr->SetRange({startLoc, Lexer()->GetToken().End()}); + if (expr->Arguments().size() != 1 || !expr->Arguments().front()->IsStringLiteral()) { + LogError(diagnostic::ONLY_STRING_LITERAL_IN_INIT_MODULE, {}, expr->Start()); + return AllocBrokenStatement(startLoc); + } + // In order to build relationship between the current program and initModule program. + importPathManager_->GatherImportMetadata(const_cast(GetContext().GetProgram()), + util::ImportFlags::NONE, expr->Arguments().front()->AsStringLiteral()); + return AllocNode(expr); +} + ir::Statement *ETSParser::ParseAnnotationsInStatement(StatementParsingFlags flags) { Lexer()->NextToken(); // eat '@' diff --git a/ets2panda/parser/parserFlags.h b/ets2panda/parser/parserFlags.h index a7ac93e3ba4f175ce31ba63dd7a8ab85fe4d6ef8..5f307af35408ea5ddf89ae0fc2fbd3618142f674 100644 --- a/ets2panda/parser/parserFlags.h +++ b/ets2panda/parser/parserFlags.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -69,6 +69,7 @@ enum class StatementParsingFlags : uint32_t { GLOBAL = 1U << 1U, IF_ELSE = 1U << 2U, LABELLED = 1U << 3U, + INIT_MODULE = 1U << 4U, STMT_LEXICAL_SCOPE_NEEDED = IF_ELSE | LABELLED, STMT_GLOBAL_LEXICAL = GLOBAL | ALLOW_LEXICAL, diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index c71ad06628d3c17756b408eace5e79973cf7e316..30da9aa1ce5d3216d0d79c7e9961bf3649ddbe3c 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -424,6 +424,7 @@ protected: virtual ir::AnnotatedExpression *ParseVariableDeclaratorKey(VariableParsingFlags flags); virtual ir::Statement *ParseAnnotationsInStatement(StatementParsingFlags flags); + virtual ir::Statement *ParseInitModuleStatement(StatementParsingFlags flags); virtual ir::VariableDeclarator *ParseVariableDeclarator(ir::Expression *init, lexer::SourcePosition startLoc, VariableParsingFlags flags); virtual ir::VariableDeclarator *ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags, diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index dfff3756ec9406aa2265af9755f401aec67a1051..c4ff7e348a8549fe156fc6026befbd66c0bb683e 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -206,6 +206,11 @@ ir::Statement *ParserImpl::ParseStatementBasedOnTokenType(StatementParsingFlags } } +ir::Statement *ParserImpl::ParseInitModuleStatement([[maybe_unused]] StatementParsingFlags flags) +{ + ES2PANDA_UNREACHABLE(); +} + ir::Statement *ParserImpl::ParseAnnotationsInStatement([[maybe_unused]] StatementParsingFlags flags) { ES2PANDA_UNREACHABLE(); @@ -674,9 +679,11 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou ir::Statement *ParserImpl::ParseExpressionStatement(StatementParsingFlags flags) { + if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_INIT_MODULE && IsETSParser()) { + return ParseInitModuleStatement(flags); + } const auto startPos = lexer_->Save(); ParserStatus savedStatus = context_.Status(); - auto tokenType = lexer_->GetToken().Type(); if (tokenType == lexer::TokenType::KEYW_PUBLIC || tokenType == lexer::TokenType::KEYW_PRIVATE || tokenType == lexer::TokenType::KEYW_PROTECTED) { diff --git a/ets2panda/public/CMakeLists.txt b/ets2panda/public/CMakeLists.txt index 5579b1ef088fe75dd05bfecab8ee6a564e8b1cc0..a5f869fddbdb4cdd8df5246030e02009617fa577 100644 --- a/ets2panda/public/CMakeLists.txt +++ b/ets2panda/public/CMakeLists.txt @@ -200,6 +200,7 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/checker/types/ets/etsTupleType.h ${ES2PANDA_ROOT}/checker/types/signature.h ${ES2PANDA_ROOT}/ir/ets/etsPrimitiveType.h + ${ES2PANDA_ROOT}/ir/ets/etsIntrinsicNode.h ${ES2PANDA_ROOT}/ir/as/namedType.h ${ES2PANDA_ROOT}/ir/statements/throwStatement.h ${ES2PANDA_ROOT}/ir/statements/forOfStatement.h @@ -439,6 +440,7 @@ set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/checker/types/ets/intType.yaml ${LIBGEN_DIR}/gen/headers/checker/types/ts/objectLiteralType.yaml ${LIBGEN_DIR}/gen/headers/checker/types/typeFlag.yaml + ${LIBGEN_DIR}/gen/headers/ir/ets/etsIntrinsicNode.yaml ${LIBGEN_DIR}/gen/headers/ir/ets/etsPackageDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/ets/etsImportDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/ets/etsStructDeclaration.yaml diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative1.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative1.ets new file mode 100644 index 0000000000000000000000000000000000000000..683b62432d78c2310e478d5163f7119738a2ecf2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative1.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 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. + */ + +function foo() { + /* @@ label */initModule('./module_to_init.ets') +} + +/* @@@ label Error SyntaxError: initModule() must only be called immediately after the import statement, and before any other declarations or statements. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative2.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative2.ets new file mode 100644 index 0000000000000000000000000000000000000000..7887e38abf24d0f0ba6795abf5924fb16e7a7d04 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative2.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 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. + */ + +class A { +} + +/* @@ label */initModule('./module_to_init.ets') + +/* @@@ label Error SyntaxError: initModule() must only be called immediately after the import statement, and before any other declarations or statements. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative3.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative3.ets new file mode 100644 index 0000000000000000000000000000000000000000..18a7108e9362871bd65fdae78bc7f8fe837237c5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative3.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 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. + */ + +let b = 1 +/* @@ label */initModule('./module_to_init.ets') + +/* @@@ label Error SyntaxError: initModule() must only be called immediately after the import statement, and before any other declarations or statements. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative4.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative4.ets new file mode 100644 index 0000000000000000000000000000000000000000..e9d9ffd119ac1d841104d0a2410b52432eeed989 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative4.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 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. + */ + +/* @@ label */initModule(1) + +/* @@@ label Error SyntaxError: initModule() only accept string literal as argument. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative5.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative5.ets new file mode 100644 index 0000000000000000000000000000000000000000..5bf4e846f0e26c47d2ea2dec71a63e188425878b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative5.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 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. + */ + +initModule( + +/* @@? 16:1 Error SyntaxError: initModule() only accept string literal as argument. */ +/* @@? 20:1 Error SyntaxError: Expected ')', got 'end of stream'. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative6.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative6.ets new file mode 100644 index 0000000000000000000000000000000000000000..3bc35e5a51645f08e146a6df47374a86ebd24a1e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative6.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 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. + */ + +initModule) + +/* @@? 16:11 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 21:1 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 21:1 Error SyntaxError: Unexpected token, expected ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative7.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative7.ets new file mode 100644 index 0000000000000000000000000000000000000000..f91b70836f001ed2914c4084a54783c66d405b02 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative7.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 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. + */ + +/* @@ label */initmodule('./module_to_init.ets') + +/* @@@ label Error TypeError: Unresolved reference initmodule */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative8.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative8.ets new file mode 100644 index 0000000000000000000000000000000000000000..20adc6d8ff0fe764e5008a6caa7ac6a1ba22f2c4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative8.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 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. + */ + +initModule() + +/* @@? 16:1 Error SyntaxError: initModule() only accept string literal as argument. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/module_to_init.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/module_to_init.ets new file mode 100644 index 0000000000000000000000000000000000000000..98cc750cb772d154734be771ffbc91e8ae72f062 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/module_to_init.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 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. + */ + +let a = 10 diff --git a/ets2panda/test/runtime/ets/init_module_tests/initModule1.ets b/ets2panda/test/runtime/ets/init_module_tests/initModule1.ets new file mode 100644 index 0000000000000000000000000000000000000000..24b90d9d7ef44303a3c7cb8eef18c8916202654e --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/initModule1.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 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. + */ +/*--- + files: ['./moduleToInit/moduleToInit.ets', ./moduleToInit/moduleToInit1.ets] +---*/ + +initModule('./moduleToInit/moduleToInit') +initModule('./moduleToInit/moduleToInit1') + +function main() { + console.log('In main function') +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/init_module_tests/initModule1.ets.expected b/ets2panda/test/runtime/ets/init_module_tests/initModule1.ets.expected new file mode 100644 index 0000000000000000000000000000000000000000..b92a6321b5abe06d9d9356e25ef213cefeb05361 --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/initModule1.ets.expected @@ -0,0 +1,16 @@ +# Copyright (c) 2025 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. +# +Init Module Success +Init Module Success1 +In main function diff --git a/ets2panda/test/runtime/ets/init_module_tests/initModule2.ets b/ets2panda/test/runtime/ets/init_module_tests/initModule2.ets new file mode 100644 index 0000000000000000000000000000000000000000..adc06abe8d92e6c202347ae13ed3d338ed24a941 --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/initModule2.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 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. + */ +/*--- +files: ['./moduleToInit/moduleToInit.ets', ./moduleToInit/moduleToInit1.ets] +---*/ + +initModule('./moduleToInit/moduleToInit1') +initModule('./moduleToInit/moduleToInit') + +function main() { + console.log('In main function') +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/init_module_tests/initModule2.ets.expected b/ets2panda/test/runtime/ets/init_module_tests/initModule2.ets.expected new file mode 100644 index 0000000000000000000000000000000000000000..1572ade0ca1f758ffdacba32c868bbbcc8ce7d38 --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/initModule2.ets.expected @@ -0,0 +1,16 @@ +# Copyright (c) 2025 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. +# +Init Module Success1 +Init Module Success +In main function diff --git a/ets2panda/test/runtime/ets/init_module_tests/initModule3.ets b/ets2panda/test/runtime/ets/init_module_tests/initModule3.ets new file mode 100644 index 0000000000000000000000000000000000000000..7e7840af330a4553c6e8c1831cdf0705d62da6fe --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/initModule3.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 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. + */ +/*--- +files: ['./moduleToInit/moduleToInit.ets'] +---*/ + +initModule('./moduleToInit/moduleToInit') +initModule('./moduleToInit/moduleToInit') +initModule('./moduleToInit/moduleToInit') + +function main() { + console.log('In main function') +} diff --git a/ets2panda/test/runtime/ets/init_module_tests/initModule3.ets.expected b/ets2panda/test/runtime/ets/init_module_tests/initModule3.ets.expected new file mode 100644 index 0000000000000000000000000000000000000000..b9d13beccf0e06120d2833bd774e0585d7d298b2 --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/initModule3.ets.expected @@ -0,0 +1,15 @@ +# Copyright (c) 2025 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. +# +Init Module Success +In main function diff --git a/ets2panda/test/runtime/ets/init_module_tests/initModule4.ets b/ets2panda/test/runtime/ets/init_module_tests/initModule4.ets new file mode 100644 index 0000000000000000000000000000000000000000..53859c852ffb76a15a5250115f83912e86bfd11f --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/initModule4.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 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. + */ +/*--- +files: ['./moduleToInit/moduleToInit2.ets'] +---*/ + +initModule('./moduleToInit/moduleToInit2.ets') +console.log('Initializing initModule4.ets') + +function main() { + console.log('In main function of initModule4.ets') +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/init_module_tests/initModule4.ets.expected b/ets2panda/test/runtime/ets/init_module_tests/initModule4.ets.expected new file mode 100644 index 0000000000000000000000000000000000000000..fb3246c4203b9e9bacc03aa737ddeab703506b72 --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/initModule4.ets.expected @@ -0,0 +1,17 @@ +# Copyright (c) 2025 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. +# +Init Module Success1 +Initializing moduleToInit2.ets +Initializing initModule4.ets +In main function of initModule4.ets diff --git a/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit.ets b/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit.ets new file mode 100644 index 0000000000000000000000000000000000000000..8df2a057aadaaf57918fba6f590cbc29a86fb99d --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 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. + */ +/*--- + tags: [compile-only] +---*/ + +console.log('Init Module Success') \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit1.ets b/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit1.ets new file mode 100644 index 0000000000000000000000000000000000000000..9d95274aa2af3cd13104414457d1c7f1841e919d --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit1.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 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. + */ +/*--- + tags: [compile-only] +---*/ + +console.log('Init Module Success1') \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit2.ets b/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit2.ets new file mode 100644 index 0000000000000000000000000000000000000000..423925508a4669fb48091ffce112fbf071bd51e8 --- /dev/null +++ b/ets2panda/test/runtime/ets/init_module_tests/moduleToInit/moduleToInit2.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 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. + */ +/*--- + files: ['./moduleToInit1.ets'] + tags: [compile-only] +---*/ + +initModule('./moduleToInit1.ets') +console.log('Initializing moduleToInit2.ets') \ No newline at end of file diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index fef5d62ff27ad612df4680c0c147b50164cb8958..43a5a991a02fab47dbabba044673fc86068c8b83 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1287,3 +1287,11 @@ syntax: - name: FUNC_EXPR id: 320 message: "Function expressions are not supported, use arrow functions instead" + +- name: ONLY_STRING_LITERAL_IN_INIT_MODULE + id: 321 + message: "initModule() only accept string literal as argument." + +- name: INIT_MODULE_DECLARATION_POSITION + id: 322 + message: "initModule() must only be called immediately after the import statement, and before any other declarations or statements."