From 5f3e506349fb472eb91ecd6f725db55e4dc94baf Mon Sep 17 00:00:00 2001 From: Csaba Hurton Date: Tue, 3 Jun 2025 11:07:13 +0200 Subject: [PATCH] Update Helpers::IsStdLib logic Make it indifferent from module names Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICCALN Testing: * all test-u-runner test suits Change-Id: I68caa76c9371fca95c9dfed43e50c748235ecd77 Signed-off-by: Csaba Hurton --- .../ets/topLevelStmts/topLevelStmts.cpp | 1 - ets2panda/parser/ETSparser.cpp | 19 +++++++++++- ets2panda/parser/ETSparser.h | 3 +- ets2panda/parser/program/program.cpp | 29 +++++++++++++++++++ ets2panda/parser/program/program.h | 10 ++++--- .../test/runtime/ets/explicitStdLibImport.ets | 20 +++++++++++++ ets2panda/util/helpers.cpp | 16 +--------- ets2panda/util/importPathManager.cpp | 5 ++-- ets2panda/varbinder/ETSBinder.h | 5 ++++ 9 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 ets2panda/test/runtime/ets/explicitStdLibImport.ets diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp index 80439e2eff..4951c1d569 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp @@ -96,7 +96,6 @@ bool TopLevelStatements::Perform(public_lib::Context *ctx, parser::Program *prog { CheckFileHeaderFlag(program); auto imports = ImportExportDecls(program->VarBinder()->AsETSBinder(), ctx->parser->AsETSParser()); - imports.ParseDefaultSources(); if (!CheckProgramSourcesConsistency(program)) { // NOTE(vpukhov): enforce compilation failure } diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 36001a7946..8f5184ae52 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -111,6 +111,7 @@ std::unique_ptr ETSParser::InitLexer(const SourceFile &sourceFile) void ETSParser::ParseProgram(ScriptKind kind) { + ParseImplicitlyImportedStdLib(); lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); Lexer()->NextToken(); GetProgram()->SetKind(kind); @@ -165,6 +166,16 @@ void ETSParser::ParseFileHeaderFlag(lexer::SourcePosition startLoc, ArenaVector< } } +void ETSParser::ParseImplicitlyImportedStdLib() +{ + std::string importStdlibFile; + for (const auto &path : util::Helpers::StdLib()) { + importStdlibFile += "import * from \"" + path + "\";"; + } + auto imports = ParseDefaultSources(DEFAULT_IMPORT_SOURCE_FILE, importStdlibFile); + GetProgram()->VarBinder()->AsETSBinder()->SetDefaultImports(std::move(imports)); +} + ir::ETSModule *ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, ArenaVector &statements) { ETSNolintParser etsnolintParser(this); @@ -239,7 +250,6 @@ ArenaVector ETSParser::ParseDefaultSources(std::stri GetContext().Status() |= ParserStatus::IN_DEFAULT_IMPORTS; auto statements = ParseImportDeclarations(); - GetContext().Status() &= ~ParserStatus::IN_DEFAULT_IMPORTS; std::vector programs; auto *ctx = GetProgram()->VarBinder()->GetContext(); @@ -257,6 +267,7 @@ ArenaVector ETSParser::ParseDefaultSources(std::stri AddExternalSource(ParseSources()); } } + GetContext().Status() &= ~ParserStatus::IN_DEFAULT_IMPORTS; return statements; } @@ -284,6 +295,9 @@ void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo & auto src = importData.HasSpecifiedDeclPath() ? importData.declPath : importData.resolvedSource; SourceFile sf {src, extSrc->View().Utf8(), importData.resolvedSource, false, importData.HasSpecifiedDeclPath()}; parser::Program *newProg = ParseSource(sf); + if ((GetContext().Status() & ParserStatus::IN_DEFAULT_IMPORTS) != 0) { + newProg->SetIsImportedFromStdLib(true); + } if (!importData.IsImplicitPackageImported() || newProg->IsPackage()) { AddDirectImportsToDirectExternalSources(directImportsFromMainSource, newProg); // don't insert the separate modules into the programs, when we collect implicit package imports @@ -426,6 +440,9 @@ parser::Program *ETSParser::ParseSource(const SourceFile &sourceFile) } else { script = ParseETSGlobalScript(startLoc, statements); } + if ((GetContext().Status() & ParserStatus::IN_PACKAGE) != 0) { + GetContext().Status() &= ~ParserStatus::IN_PACKAGE; + } program->SetAst(script); return program; } diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 1d7b1ee848..42acb56cff 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -81,7 +81,7 @@ public: template static constexpr bool STATIC_FALSE = false; - + static constexpr std::string_view DEFAULT_IMPORT_SOURCE_FILE = ".ets"; std::string_view FormattingFileName() { return GetContext().FormattingFileName(); @@ -174,6 +174,7 @@ private: void ParseProgram(ScriptKind kind) override; [[nodiscard]] std::unique_ptr InitLexer(const SourceFile &sourceFile) override; ir::ETSPackageDeclaration *ParsePackageDeclaration(); + void ParseImplicitlyImportedStdLib(); void AddPackageSourcesToParseList(); ArenaVector ParseTopLevelStatements(); ir::AstNode *HandleAmbientDeclaration(ir::ModifierFlags &memberModifiers, diff --git a/ets2panda/parser/program/program.cpp b/ets2panda/parser/program/program.cpp index 572ce976dc..9791dc0015 100644 --- a/ets2panda/parser/program/program.cpp +++ b/ets2panda/parser/program/program.cpp @@ -179,6 +179,35 @@ bool Program::IsASTChecked() ((programFlags_ & ProgramFlags::AST_CHECK_PROCESSED) != 0U); } +bool Program::IsImplicitImportOrCompiledProgramIsStdLib() const +{ + // NOTE (hurton) 1st cond: for stdlib sources being implicitly imported + // 2nd cond: to cover cases when the stdlib is being compiled + for (auto varbinder : varbinders_) { + if (isImportedFromStdLib_ || + varbinder.second->Program()->FileNameWithExtension().Is(ETSParser::DEFAULT_IMPORT_SOURCE_FILE)) { + return true; + } + } + + return false; +} + +bool Program::IsStdLib() const +{ + if (IsImplicitImportOrCompiledProgramIsStdLib() || ModuleName().Is("std/math/consts")) { + return true; + } + + for (auto importDecls : VarBinder()->AsETSBinder()->GetDefaultImports()) { + if (AbsoluteName().StartsWith(importDecls->ImportMetadata().resolvedSource)) { + return true; + } + } + + return false; +} + Program::~Program() // NOLINT(modernize-use-equals-default) { #ifndef NDEBUG diff --git a/ets2panda/parser/program/program.h b/ets2panda/parser/program/program.h index c29543942c..e48ca6d977 100644 --- a/ets2panda/parser/program/program.h +++ b/ets2panda/parser/program/program.h @@ -291,11 +291,12 @@ public: return isASTlowered_; } - bool IsStdLib() const + bool IsImplicitImportOrCompiledProgramIsStdLib() const; + bool IsStdLib() const; + + void SetIsImportedFromStdLib(bool isImportedFromStdLib) { - // NOTE (hurton): temporary solution, needs rework when std sources are renamed - return (ModuleName().Mutf8().rfind("std.", 0) == 0) || (ModuleName().Mutf8().rfind("escompat", 0) == 0) || - (FileName().Is("etsstdlib")); + isImportedFromStdLib_ = isImportedFromStdLib; } varbinder::ClassScope *GlobalClassScope(); @@ -391,6 +392,7 @@ private: std::vector> declGenExportNodes_; ArenaVector functionScopes_; std::unordered_map> fileDependencies_; + bool isImportedFromStdLib_ {false}; private: ArenaMap varbinders_; diff --git a/ets2panda/test/runtime/ets/explicitStdLibImport.ets b/ets2panda/test/runtime/ets/explicitStdLibImport.ets new file mode 100644 index 0000000000..66c63d79ff --- /dev/null +++ b/ets2panda/test/runtime/ets/explicitStdLibImport.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. + */ + +import {max as MMAAXX} from "std/math" + +function main() { + assertEQ(MMAAXX(0, 100), 100) +} \ No newline at end of file diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index 41e971809e..5d6f6fdda8 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -708,21 +708,7 @@ std::vector const &Helpers::StdLib() bool Helpers::IsStdLib(const parser::Program *program) { - // NOTE(rsipka): early check: if program is not in a package then it is not part of the stdlib either - if (!program->IsPackage()) { - return false; - } - - auto fileFolder = program->ModuleName().Mutf8(); - std::replace(fileFolder.begin(), fileFolder.end(), *compiler::Signatures::METHOD_SEPARATOR.begin(), - *compiler::Signatures::NAMESPACE_SEPARATOR.begin()); - - if (fileFolder == "std/math/consts") { - return true; - } - - auto const &stdlib = StdLib(); - return std::count(stdlib.begin(), stdlib.end(), fileFolder) != 0; + return program->IsStdLib(); } checker::Type *Helpers::CheckReturnTypeOfCheck([[maybe_unused]] const ir::AstNode *const node, diff --git a/ets2panda/util/importPathManager.cpp b/ets2panda/util/importPathManager.cpp index 7cf0466927..2d8996aacd 100644 --- a/ets2panda/util/importPathManager.cpp +++ b/ets2panda/util/importPathManager.cpp @@ -74,8 +74,9 @@ ImportPathManager::ImportMetadata ImportPathManager::GatherImportMetadata(parser return ImportMetadata {util::ImportFlags::NONE, Language::Id::COUNT, ERROR_LITERAL}; } - globalProgram_->AddFileDependencies(std::string(curModulePath), std::string(resolvedImportPath)); - + if (!program->IsImplicitImportOrCompiledProgramIsStdLib()) { + globalProgram_->AddFileDependencies(std::string(curModulePath), std::string(resolvedImportPath)); + } ImportMetadata importData {importFlags}; importData.resolvedSource = resolvedImportPath; if (resolvedIsDynamic) { diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 140596eccd..9dc62dd7cc 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -200,6 +200,11 @@ public: defaultImports_ = std::move(defaultImports); } + ArenaVector GetDefaultImports() const noexcept + { + return defaultImports_; + } + void AddDynamicImport(ir::ETSImportDeclaration *import); [[nodiscard]] const ArenaVector &DynamicImports() const noexcept -- Gitee