diff --git a/aot/options.cpp b/aot/options.cpp index 8c5c67f03b103ca601f9601a0822cb89f3f9f5fb..23d451e4c99dd2e4aad225669db374a2b2ec41f3 100644 --- a/aot/options.cpp +++ b/aot/options.cpp @@ -52,6 +52,7 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg op_debug_info("debug-info", false, "Compile with debug info"); panda::PandArg op_dump_debug_info("dump-debug-info", false, "Dump debug info"); panda::PandArg op_opt_level("opt-level", 0, "Compiler optimization level (options: 0 | 1 | 2)"); + panda::PandArg op_ets_module("ets-module", false, "Compile the input as ets-module"); auto constexpr DEFAULT_THREAD_COUNT = 2; panda::PandArg op_thread_count("thread", DEFAULT_THREAD_COUNT, "Number of worker threads"); @@ -74,6 +75,7 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&op_dump_debug_info); argparser_->Add(&op_opt_level); + argparser_->Add(&op_ets_module); argparser_->Add(&op_thread_count); argparser_->Add(&op_size_stat); @@ -206,6 +208,7 @@ bool Options::Parse(int argc, const char **argv) compiler_options_.std_lib = std_lib.GetValue(); compiler_options_.gen_std_lib = gen_std_lib.GetValue(); compiler_options_.arkts_config = arkts_config.GetValue(); + compiler_options_.is_ets_module = op_ets_module.GetValue(); return true; } diff --git a/binder/ETSBinder.cpp b/binder/ETSBinder.cpp index a3dc45595d5d1ac380394b8b24a217411c33cb6a..dcbb061f71e8eceae5aaa4cc3a478f118ed42133 100644 --- a/binder/ETSBinder.cpp +++ b/binder/ETSBinder.cpp @@ -631,16 +631,21 @@ void ETSBinder::BuildFunctionalInterfaceName(ir::ETSFunctionType *func_type) util::StringView signature_name(signature_string); FormFunctionalInterfaceName(functional_interface_name, signature_name); functional_interface->Id()->SetName(functional_interface_name.View()); - functional_interface->SetInternalName(functional_interface->Id()->Name()); + util::UString internal_name(Program()->GetPackageName(), Allocator()); + internal_name.Append(compiler::Signatures::METHOD_SEPARATOR); + internal_name.Append(functional_interface->Id()->Name()); + functional_interface->SetInternalName(internal_name.View()); checker::ETSObjectType *functional_interface_type = functional_interface->TsType()->AsETSObjectType(); functional_interface_type->SetName(functional_interface->Id()->Name()); - functional_interface_type->SetAssemblerName(functional_interface->Id()->Name()); + functional_interface_type->SetAssemblerName(internal_name.View()); auto *invoke_func_scope = invoke_func->Scope(); invoke_func_scope->BindName(functional_interface->Id()->Name()); - util::UString invoke_internal_name(invoke_func_scope->Name(), Allocator()); + util::UString invoke_internal_name(Program()->GetPackageName(), Allocator()); + invoke_internal_name.Append(compiler::Signatures::METHOD_SEPARATOR); + invoke_internal_name.Append(invoke_func_scope->Name()); invoke_internal_name.Append(compiler::Signatures::METHOD_SEPARATOR); invoke_internal_name.Append(invoke_func->Id()->Name()); std::stringstream invoke_signature_ss; diff --git a/binder/recordTable.cpp b/binder/recordTable.cpp index 7dcd061c5186066f2b2d37be61c812809f45b67b..2c1b8cee6ec26fd02a5327ae0216fb9e597564a0 100644 --- a/binder/recordTable.cpp +++ b/binder/recordTable.cpp @@ -96,7 +96,7 @@ util::StringView RecordTable::RecordName() const return std::get(record_)->InternalName(); } if (std::holds_alternative(record_)) { - return std::get(record_)->Id()->Name(); + return std::get(record_)->InternalName(); } ASSERT(std::holds_alternative(record_)); diff --git a/checker/ets/typeCreation.cpp b/checker/ets/typeCreation.cpp index a00c17b23a48f7aed93cbfb8ed3d8a87eaa044b2..7f33fa9f27400812d4f7272bb416b7a2de82a84c 100644 --- a/checker/ets/typeCreation.cpp +++ b/checker/ets/typeCreation.cpp @@ -258,7 +258,8 @@ ETSObjectType *ETSChecker::CreateNewETSObjectType(util::StringView name, ir::Ast prefix = containing_obj_type->AssemblerName(); } else if (decl_node->GetTopStatement()->Type() != ir::AstNodeType::BLOCK_STATEMENT) { // TODO(): should not occur, fix for TS_INTERFACE_DECLARATION - prefix = ""; + ASSERT(decl_node->IsTSInterfaceDeclaration()); + assembler_name = decl_node->AsTSInterfaceDeclaration()->InternalName(); } else { auto *program = static_cast(decl_node->GetTopStatement())->Program(); prefix = program->GetPackageName(); diff --git a/compiler/core/ETSemitter.cpp b/compiler/core/ETSemitter.cpp index 7a12236381eb74c8980dc2d1ab69c976f3ebe32b..d8b7cfc2a5efd640e3d8fff38dbbbc06085499ba 100644 --- a/compiler/core/ETSemitter.cpp +++ b/compiler/core/ETSemitter.cpp @@ -422,7 +422,7 @@ void ETSEmitter::GenInterfaceRecord(const ir::TSInterfaceDeclaration *interface_ { auto *base_type = interface_decl->TsType()->AsETSObjectType(); - auto interface_record = pandasm::Record(base_type->Name().Mutf8(), Program()->lang); + auto interface_record = pandasm::Record(interface_decl->InternalName().Mutf8(), Program()->lang); if (external) { interface_record.metadata->SetAttribute(Signatures::EXTERNAL); @@ -439,7 +439,10 @@ void ETSEmitter::GenInterfaceRecord(const ir::TSInterfaceDeclaration *interface_ interface_record.metadata->SetAttributeValue(Signatures::EXTENDS_ATTRIBUTE, Signatures::BUILTIN_OBJECT); for (auto *it : base_type->Interfaces()) { - interface_record.metadata->SetAttributeValue(Signatures::IMPLEMENTS_ATTRIBUTE, it->Name().Mutf8()); + auto *decl_node = it->GetDeclNode(); + ASSERT(decl_node->IsTSInterfaceDeclaration()); + std::string name = decl_node->AsTSInterfaceDeclaration()->InternalName().Mutf8(); + interface_record.metadata->SetAttributeValue(Signatures::IMPLEMENTS_ATTRIBUTE, name); } GenClassInheritedFields(base_type, interface_record); @@ -488,7 +491,10 @@ void ETSEmitter::GenClassRecord(const ir::ClassDefinition *class_def, bool exter } for (auto *it : base_type->Interfaces()) { - class_record.metadata->SetAttributeValue(Signatures::IMPLEMENTS_ATTRIBUTE, it->Name().Mutf8()); + auto *decl_node = it->GetDeclNode(); + ASSERT(decl_node->IsTSInterfaceDeclaration()); + std::string name = decl_node->AsTSInterfaceDeclaration()->InternalName().Mutf8(); + class_record.metadata->SetAttributeValue(Signatures::IMPLEMENTS_ATTRIBUTE, name); } if (!class_def->IsAbstract()) { diff --git a/compiler/core/compilerImpl.cpp b/compiler/core/compilerImpl.cpp index a068607eb341f4e1bd4a505230b03f833eba3b9c..ae3419bceac8adef39c3179b69c4b3b40c2d45de 100644 --- a/compiler/core/compilerImpl.cpp +++ b/compiler/core/compilerImpl.cpp @@ -91,6 +91,7 @@ static pandasm::Program *CreateCompiler(const CompilationUnit &unit, const EmitC { ArenaAllocator allocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true); auto program = parser::Program::NewProgram(&allocator); + program.MarkEntry(); auto parser = Parser(&program, unit.options, static_cast(unit.raw_parser_status)); auto checker = Checker(); diff --git a/es2panda.h b/es2panda.h index 0eae7cfd5d7da98ee94a965229c35f307b9c93b6..0721785b1ded278780122bf63b70b26d68ec38c5 100644 --- a/es2panda.h +++ b/es2panda.h @@ -61,6 +61,7 @@ struct SourceFile { struct CompilerOptions { // NOLINTBEGIN(misc-non-private-member-variables-in-classes) bool is_debug {}; + bool is_ets_module {}; bool is_eval {}; bool is_direct_eval {}; bool is_function_eval {}; diff --git a/ir/ets/etsImportSource.h b/ir/ets/etsImportSource.h index 0502d2d43128c34b874e52a2940e2bee767947f6..7b0c56dfc8bc5a1ec80667b10a2e681d49e81b80 100644 --- a/ir/ets/etsImportSource.h +++ b/ir/ets/etsImportSource.h @@ -25,7 +25,7 @@ namespace panda::es2panda::ir { class ImportSource { public: - explicit ImportSource(ir::StringLiteral *source, bool is_file) : source_(source), is_file_(is_file) {} + explicit ImportSource(ir::StringLiteral *source) : source_(source) {} NO_COPY_SEMANTIC(ImportSource); NO_MOVE_SEMANTIC(ImportSource); ~ImportSource() = default; @@ -40,14 +40,8 @@ public: return source_; } - bool IsFile() const - { - return is_file_; - } - private: ir::StringLiteral *source_ {}; - bool is_file_ {}; }; } // namespace panda::es2panda::ir #endif \ No newline at end of file diff --git a/parser/ETSparser.cpp b/parser/ETSparser.cpp index 1b4527cf4df62fc781f2bfdaee0aefaf7a9d45a1..04928f6602590a88392656d8d227e58383231c5d 100644 --- a/parser/ETSparser.cpp +++ b/parser/ETSparser.cpp @@ -335,11 +335,16 @@ std::tuple, bool> ETSParser::CollectUserSources(const s if (!panda::os::file::File::IsDirectory(resolved_path)) { if (!panda::os::file::File::IsRegularFile(resolved_path)) { - ThrowSyntaxError("Incorrect path."); + const std::string module_name = resolved_path + ".ets"; + if (!panda::os::file::File::IsRegularFile(module_name)) { + ThrowSyntaxError("Incorrect path."); + } + user_paths.emplace_back(std::string(path + ".ets")); + return {user_paths, true}; } user_paths.emplace_back(path); - return {user_paths, true}; + return {user_paths, false}; } #ifdef USE_UNIX_SYSCALL @@ -1876,6 +1881,19 @@ void ETSParser::ParsePackageDeclaration(ArenaVector &statements auto start_loc = Lexer()->GetToken().Start(); if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_PACKAGE) { + if (!IsETSModule() && GetProgram()->IsEntryPoint()) { + return; + } + + auto base_name = GetProgram()->SourceFile().Utf8(); + base_name = base_name.substr(base_name.find_last_of(panda::os::file::File::GetPathDelim()) + 1); + const size_t idx = base_name.find_last_of("."); + if (idx != std::string::npos) { + base_name = base_name.substr(0, idx); + } + + GetProgram()->SetPackageName(base_name); + return; } @@ -1935,13 +1953,18 @@ std::tuple> ETSParser::ParseFromCla } ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_STRING); - std::vector user_parths; - bool is_file = false; - + std::vector user_paths; + bool is_module = false; auto import_path = Lexer()->GetToken().Ident(); if ((GetContext().Status() & ParserStatus::IN_DEFAULT_IMPORTS) == 0) { - std::tie(user_parths, is_file) = CollectUserSources(import_path.Mutf8()); + std::tie(user_paths, is_module) = CollectUserSources(import_path.Mutf8()); + } + + if (is_module) { + auto pos = import_path.Mutf8().find_last_of(panda::os::file::File::GetPathDelim()); + util::UString base_name(import_path.Mutf8().substr(0, pos), Allocator()); + import_path = base_name.View(); } auto *source = AllocNode(import_path); @@ -1949,8 +1972,8 @@ std::tuple> ETSParser::ParseFromCla Lexer()->NextToken(); - auto *import_source = Allocator()->New(source, is_file); - return {import_source, user_parths}; + auto *import_source = Allocator()->New(source); + return {import_source, user_paths}; } void ETSParser::ParseArkTsConfig() @@ -2391,7 +2414,7 @@ ir::Statement *ETSParser::ParseImportDeclaration([[maybe_unused]] StatementParsi ArenaVector specifiers(Allocator()->Adapter()); ir::ImportSource *import_source = nullptr; - std::vector user_parths; + std::vector user_paths; if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) { ir::AstNode *ast_node = ParseImportSpecifiers(&specifiers); @@ -2401,9 +2424,9 @@ ir::Statement *ETSParser::ParseImportDeclaration([[maybe_unused]] StatementParsi ConsumeSemicolon(ast_node->AsTSImportEqualsDeclaration()); return ast_node->AsTSImportEqualsDeclaration(); } - std::tie(import_source, user_parths) = ParseFromClause(true); + std::tie(import_source, user_paths) = ParseFromClause(true); } else { - std::tie(import_source, user_parths) = ParseFromClause(false); + std::tie(import_source, user_paths) = ParseFromClause(false); } lexer::SourcePosition end_loc = import_source->Source()->End(); diff --git a/parser/ETSparser.h b/parser/ETSparser.h index afd6c932289c408051dc16e749f86f769f0353e4..9cc1d1b0c1b2642f8c4f413c70062ad8bb71f6a2 100644 --- a/parser/ETSparser.h +++ b/parser/ETSparser.h @@ -181,6 +181,11 @@ private: return GetOptions().arkts_config; } + bool IsETSModule() const + { + return GetOptions().is_ets_module; + } + util::StringView FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id) override; ir::ModifierFlags ParseTypeVarianceModifier(TypeAnnotationParsingOptions *options); diff --git a/parser/program/program.h b/parser/program/program.h index 87aa224676ce27fd4d0303e534675c0efecc7750..19b65729a1b2367529b2673a36ffd37a12dec201 100644 --- a/parser/program/program.h +++ b/parser/program/program.h @@ -188,6 +188,16 @@ public: absoule_name_ = util::UString(absoule_name, Allocator()).View(); } + const bool &IsEntryPoint() const + { + return entry_point_; + } + + void MarkEntry() + { + entry_point_ = true; + } + binder::ClassScope *GlobalClassScope(); const binder::ClassScope *GlobalClassScope() const; @@ -212,6 +222,7 @@ private: ExternalSource external_sources_; ScriptKind kind_ {}; ScriptExtension extension_ {}; + bool entry_point_; }; } // namespace panda::es2panda::parser