From 61c67e62ee304d5dd6ae8f0958da4b5b0d1ac453 Mon Sep 17 00:00:00 2001 From: Zelentsov Dmitry Date: Mon, 25 Aug 2025 17:28:21 +0300 Subject: [PATCH] Implement memory cache for declarations Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICUN1B Tests: use Test-U-Runner and CI Signed-off-by: Zelentsov Dmitry --- ets2panda/BUILD.gn | 1 + ets2panda/CMakeLists.txt | 1 + ets2panda/compiler/core/compilerImpl.cpp | 5 + ets2panda/parser/ETSparser.cpp | 121 ++++++++-------- ets2panda/parser/ETSparser.h | 5 +- ets2panda/parser/program/DeclarationCache.cpp | 130 ++++++++++++++++++ ets2panda/parser/program/DeclarationCache.h | 117 ++++++++++++++++ .../test/unit/union_normalisation_test.h | 7 +- ets2panda/test/utils/ast_verifier_test.cpp | 10 +- ets2panda/test/utils/ast_verifier_test.h | 2 +- ets2panda/test/utils/checker_test.h | 17 ++- ets2panda/util/importPathManager.cpp | 19 ++- ets2panda/util/importPathManager.h | 4 +- 13 files changed, 361 insertions(+), 78 deletions(-) create mode 100644 ets2panda/parser/program/DeclarationCache.cpp create mode 100644 ets2panda/parser/program/DeclarationCache.h diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index f3b5725553..93f8689a7f 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -499,6 +499,7 @@ libes2panda_sources = [ "parser/expressionParser.cpp", "parser/expressionTSParser.cpp", "parser/parserImpl.cpp", + "parser/program/DeclarationCache.cpp", "parser/program/entityNameVisitor.cpp", "parser/program/program.cpp", "parser/statementParser.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 13f327c3b7..729d0c3519 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -547,6 +547,7 @@ set(ES2PANDA_LIB_SRC parser/TSparser.cpp parser/ThrowingTypedParser.cpp parser/TypedParser.cpp + parser/program/DeclarationCache.cpp parser/program/entityNameVisitor.cpp parser/program/program.cpp parser/statementParser.cpp diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index 37b272b0ce..6b1b345ff7 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -35,6 +35,7 @@ #include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "compiler/lowering/checkerPhase.h" #include "evaluate/scopedDebugInfoPlugin.h" +#include "parser/program/DeclarationCache.h" #include "parser/parserImpl.h" #include "parser/JSparser.h" #include "parser/ASparser.h" @@ -123,6 +124,10 @@ void HandleGenerateDecl(const parser::Program &program, util::DiagnosticEngine & outFile << result; outFile.close(); + + // Add generated declaration to the cache + auto &declarationCache = parser::DeclarationCache::Instance(); + declarationCache.AddDeclaration(outputPath, std::make_shared(std::move(result))); } static bool CheckOptionsAfterPhase(const util::Options &options, const parser::Program &program, diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index b62cfb10da..d6c04b52fe 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -305,14 +305,15 @@ void ETSParser::AddDirectImportsToDirectExternalSources( dirExternal.emplace_back(newProg); } -void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo &parseListElem, util::UString *extSrc, +void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo &parseListElem, + std::string_view const extSrc, const ArenaVector &directImportsFromMainSource, std::vector *programs) { const auto &importData = parseListElem.importData; auto src = importData.HasSpecifiedDeclPath() ? importData.declPath : importData.resolvedSource; - ES2PANDA_ASSERT(extSrc != nullptr); - SourceFile sf {src, extSrc->View().Utf8(), importData.resolvedSource, false, importData.HasSpecifiedDeclPath()}; + ES2PANDA_ASSERT(!extSrc.empty()); + SourceFile sf {src, extSrc, importData.resolvedSource, false, importData.HasSpecifiedDeclPath()}; parser::Program *newProg = ParseSource(sf); ES2PANDA_ASSERT(newProg != nullptr); if (!importData.IsImplicitPackageImported() || newProg->IsPackage()) { @@ -378,69 +379,75 @@ bool ETSParser::TryMergeFromCache(size_t idx, ArenaVector(ss.str())); + } + } + + return declaration; +} + std::vector ETSParser::SearchForNotParsed(ArenaVector &parseList, ArenaVector &directImportsFromMainSource) { - std::vector programs; - auto notParsedElement = - std::find_if(parseList.begin(), parseList.end(), [](const auto &parseInfo) { return !parseInfo.isParsed; }); + std::vector programs {}; + + auto findNotParsed = [&parseList]() -> auto + // CC-OFFNXT(G.FMT.03-CPP) project code style + { + return std::find_if(parseList.begin(), parseList.end(), + [](const auto &parseInfo) { return !parseInfo.isParsed; }); + }; + + auto notParsedElement = findNotParsed(); while (notParsedElement != parseList.end()) { - // This parse list `paths` can grow in the meantime, so keep this index-based iteration - // NOLINTNEXTLINE(modernize-loop-convert) - for (size_t idx = 0; idx < parseList.size(); idx++) { - // check if already parsed - if (parseList[idx].isParsed) { - continue; - } + notParsedElement->isParsed = true; - if (TryMergeFromCache(idx, parseList)) { - continue; - } + const auto &data = notParsedElement->importData; + if (data.declPath.empty()) { + notParsedElement = findNotParsed(); + continue; + } - const auto &data = parseList[idx].importData; - if (data.declPath.empty()) { - importPathManager_->MarkAsParsed(data.resolvedSource); - continue; - } - ES2PANDA_ASSERT(data.lang != Language::Id::COUNT); - auto parseCandidate = data.HasSpecifiedDeclPath() ? data.declPath : data.resolvedSource; - if (GetProgram()->SourceFilePath().Is(parseCandidate)) { - importPathManager_->MarkAsParsed(data.resolvedSource); - return programs; - } + ES2PANDA_ASSERT(data.lang != Language::Id::COUNT); + auto parseCandidate = data.HasSpecifiedDeclPath() ? data.declPath : data.resolvedSource; + if (GetProgram()->SourceFilePath().Is(parseCandidate)) { + return programs; + } - std::string parseCandidateStr {parseCandidate}; - util::DiagnosticMessageParams diagParams = {parseCandidateStr}; - std::ifstream inputStream {parseCandidateStr}; - if (!inputStream) { - DiagnosticEngine().LogDiagnostic(diagnostic::OPEN_FAILED, diagParams); - return programs; // Error processing. - } - std::stringstream ss; - ss << inputStream.rdbuf(); - std::string externalSource; - if (data.IsExternalBinaryImport()) { - externalSource = std::string(data.declText); - } else { - externalSource = ss.str(); + auto preservedLang = GetContext().SetLanguage(data.lang); + + if (data.IsExternalBinaryImport()) { + ParseParseListElement(*notParsedElement, data.declText, directImportsFromMainSource, &programs); + } else { + auto declaration = GetDeclaration(std::string {parseCandidate}); + if (declaration == DeclarationCache::ABSENT) { + GetContext().SetLanguage(preservedLang); + notParsedElement = findNotParsed(); + continue; } - auto preservedLang = GetContext().SetLanguage(data.lang); - auto extSrc = Allocator()->New(externalSource, Allocator()); - importPathManager_->MarkAsParsed(data.resolvedSource); - ParseParseListElement(parseList[idx], extSrc, directImportsFromMainSource, &programs); - GetContext().SetLanguage(preservedLang); + ParseParseListElement(*notParsedElement, *declaration, directImportsFromMainSource, &programs); } - notParsedElement = - std::find_if(parseList.begin(), parseList.end(), [](const auto &parseInfo) { return !parseInfo.isParsed; }); + + GetContext().SetLanguage(preservedLang); + + notParsedElement = findNotParsed(); } + return programs; } @@ -485,7 +492,7 @@ parser::Program *ETSParser::ParseSource(const SourceFile &sourceFile) if (Context()->config->options->GetCompilationMode() == CompilationMode::GEN_ABC_FOR_EXTERNAL_SOURCE) { importPathManager_->AddImplicitPackageImportToParseList(program->SourceFile().GetAbsoluteParentFolder(), Lexer()->GetToken().Start()); - importPathManager_->MarkAsParsed(program->AbsoluteName()); + importPathManager_->MarkAsParsed(program->AbsoluteName().Utf8()); } SavedParserContext contextAfterParseDecl(this, GetContext().Status() |= ParserStatus::IN_PACKAGE); @@ -2452,7 +2459,7 @@ void ETSParser::AddPackageSourcesToParseList() Lexer()->GetToken().Start()); // Global program file is always in the same folder that we scanned, but we don't need to parse it twice - importPathManager_->MarkAsParsed(globalProgram_->AbsoluteName()); + importPathManager_->MarkAsParsed(globalProgram_->AbsoluteName().Utf8()); } //================================================================================================// diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 66ddcc044e..f65953d274 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_PARSER_CORE_ETS_PARSER_H #define ES2PANDA_PARSER_CORE_ETS_PARSER_H +#include "program/DeclarationCache.h" #include "util/arktsconfig.h" #include "util/importPathManager.h" #include "innerSourceParser.h" @@ -193,7 +194,7 @@ private: void ParseNamedExportSpecifiers(ArenaVector *specifiers, bool defaultExport); void ParseUserSources(std::vector userParths); ArenaVector ParseTopLevelDeclaration(); - void ParseParseListElement(const util::ImportPathManager::ParseInfo &parseListElem, util::UString *extSrc, + void ParseParseListElement(const util::ImportPathManager::ParseInfo &parseListElem, std::string_view extSrc, const ArenaVector &directImportsFromMainSource, std::vector *programs); bool IsDefaultImport(); @@ -210,6 +211,8 @@ private: ir::Statement *ParseImportDeclarationHelper(lexer::SourcePosition startLoc, ArenaVector &specifiers, ir::ImportKinds importKind); bool TryMergeFromCache(size_t idx, ArenaVector &parseList); + + DeclarationType GetDeclaration(std::string &&fileToParse) const; std::vector SearchForNotParsed(ArenaVector &parseList, ArenaVector &directImportsFromMainSource); parser::Program *ParseSource(const SourceFile &sourceFile); diff --git a/ets2panda/parser/program/DeclarationCache.cpp b/ets2panda/parser/program/DeclarationCache.cpp new file mode 100644 index 0000000000..cb103fb184 --- /dev/null +++ b/ets2panda/parser/program/DeclarationCache.cpp @@ -0,0 +1,130 @@ +/** + * 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 "DeclarationCache.h" +#include +#include +#include +#include "util/es2pandaMacros.h" + +namespace ark::es2panda::parser { + +UniqueSpinMutex::~UniqueSpinMutex() +{ + // Atomic with relaxed order reason: read of field + ES2PANDA_ASSERT(spin_.load(std::memory_order_relaxed) == LOCK_OFF); +}; + +// CC-OFFNXT(G.NAM.03-CPP) project code style +void UniqueSpinMutex::lock() +{ + std::int64_t test = LOCK_OFF; + // Atomic with acquire order reason: other threads should see correct value + while (!spin_.compare_exchange_weak(test, LOCK_SET, std::memory_order_acquire, std::memory_order_relaxed)) { + test = LOCK_OFF; + std::this_thread::yield(); + } +} + +// CC-OFFNXT(G.NAM.03-CPP) project code style +void UniqueSpinMutex::unlock() +{ + // Atomic with release order reason: write to field, other threads should see correct value + spin_.store(LOCK_OFF, std::memory_order_release); +} + +// CC-OFFNXT(G.NAM.03-CPP) project code style +bool UniqueSpinMutex::try_lock() +{ + std::int64_t test = LOCK_OFF; + // Atomic with acquire order reason: other threads should see correct value + return spin_.compare_exchange_strong(test, LOCK_SET, std::memory_order_acquire, std::memory_order_relaxed); +} + +// CC-OFFNXT(G.NAM.03-CPP) project code style +void ReadWriteSpinMutex::lock_shared() +{ + // Atomic with relaxed order reason: read of field + while (spin_.load(std::memory_order_relaxed) < LOCK_OFF || + // Atomic with acquire order reason: other threads should see correct value + spin_.fetch_add(1, std::memory_order_acquire) < LOCK_OFF) { + std::this_thread::yield(); + } +} + +// CC-OFFNXT(G.NAM.03-CPP) project code style +void ReadWriteSpinMutex::unlock_shared() +{ + // Atomic with release order reason: write to field, other threads should see correct value + spin_.fetch_sub(1, std::memory_order_release); +} + +// CC-OFFNXT(G.NAM.03-CPP) project code style +bool ReadWriteSpinMutex::try_lock_shared() +{ + // Atomic with relaxed order reason: read of field + return spin_.load(std::memory_order_relaxed) >= LOCK_OFF && + // Atomic with acquire order reason: other threads should see correct value + spin_.fetch_add(1, std::memory_order_acquire) >= LOCK_OFF; +} + +DeclarationCache::~DeclarationCache() +{ + ClearAll(); +} + +DeclarationCache::DeclarationCache([[maybe_unused]] Tag &&tag) {} + +//--------------------------------------------------------------------------------------------------------// +// Creates the new instance of DeclarationCache class (a singleton object) +//--------------------------------------------------------------------------------------------------------// +DeclarationCache &DeclarationCache::Instance() +{ + if (!DeclarationCache::globalDeclarationCache_) { + DeclarationCache::globalDeclarationCache_ = std::make_unique(DeclarationCache::Tag {}); + } + return *DeclarationCache::globalDeclarationCache_; +} + +void DeclarationCache::ClearAll() noexcept +{ + std::scoped_lock lock(dataGuard_); + declarations_.clear(); +} + +void DeclarationCache::RemoveDeclaration(std::string const &fileName) noexcept +{ + std::scoped_lock lock(dataGuard_); + declarations_.erase(fileName); +} + +DeclarationType DeclarationCache::GetDeclaration(std::string const &fileName) const noexcept +{ + std::shared_lock lock(dataGuard_); + auto const it = declarations_.find(fileName); + return (it != declarations_.end()) ? it->second : ABSENT; +} + +//--------------------------------------------------------------------------------------------------------// +// Adds specified declaration file to the cache (or replaces the existing one). +//--------------------------------------------------------------------------------------------------------// +DeclarationType DeclarationCache::AddDeclaration(std::string fileName, DeclarationType decl) +{ + std::scoped_lock lock(dataGuard_); + auto [it, _] = declarations_.insert_or_assign(std::move(fileName), std::move(decl)); + return it->second; +} + +} // namespace ark::es2panda::parser diff --git a/ets2panda/parser/program/DeclarationCache.h b/ets2panda/parser/program/DeclarationCache.h new file mode 100644 index 0000000000..a21e3889d7 --- /dev/null +++ b/ets2panda/parser/program/DeclarationCache.h @@ -0,0 +1,117 @@ +/** + * 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_DECLARATION_CACHE_H +#define ES2PANDA_DECLARATION_CACHE_H + +#include +#include +#include +#include +#include + +#include "libpandabase/macros.h" + +namespace ark::es2panda::parser { + +//--------------------------------------------------------------------------------------------------------------------// +// Constants used in spin-lock classes. +//--------------------------------------------------------------------------------------------------------------------// +constexpr std::int64_t LOCK_OFF = 0; +constexpr std::int64_t LOCK_SET = std::numeric_limits::min(); + +//--------------------------------------------------------------------------------------------------------------------// +// Class to provide lightweight non-blocking read/write access for multiple threads +// using the 'spinning' interlocked mutex that meets Lockable requirements. +// Note 1. Each '...Lock()' call should always have the corresponding '...Unlock()'. +// Note 2. Write lock cannot be used in recursive calls. +// Note 3. Standard template guards like 'scoped_lock' and 'unique_lock' can be used. +//--------------------------------------------------------------------------------------------------------------------// +class UniqueSpinMutex { +public: + UniqueSpinMutex() = default; + virtual ~UniqueSpinMutex(); + + NO_COPY_SEMANTIC(UniqueSpinMutex); + NO_MOVE_SEMANTIC(UniqueSpinMutex); + + // Standard library 'Lockable' requirements implementation + void lock(); // CC-OFF(G.NAM.03-CPP) project code style + void unlock(); // CC-OFF(G.NAM.03-CPP) project code style + bool try_lock(); // CC-OFF(G.NAM.03-CPP) project code style + +protected: + std::atomic_int64_t spin_ {LOCK_OFF}; +}; + +//--------------------------------------------------------------------------------------------------------------------// +// Class to provide lightweight non-blocking simultaneous read access for multiple threads and blocking write access +// for a single thread using the 'spinning' interlocked mutex that meets the SharedMutex requirements. +// Note 1. Each '...Lock()' call should always have the corresponding '...Unlock()'. +// Note 2. Write lock cannot be used in recursive calls. +// Note 3. Standard template guards like 'scoped_lock' and 'shared_lock' can be used. +//--------------------------------------------------------------------------------------------------------------------// +class ReadWriteSpinMutex final : public UniqueSpinMutex { +public: + ReadWriteSpinMutex() = default; + ~ReadWriteSpinMutex() override = default; + + NO_COPY_SEMANTIC(ReadWriteSpinMutex); + NO_MOVE_SEMANTIC(ReadWriteSpinMutex); + + // Standard library 'SharedLockable' requirements implementation + void lock_shared(); // CC-OFF(G.NAM.03-CPP) project code style + void unlock_shared(); // CC-OFF(G.NAM.03-CPP) project code style + bool try_lock_shared(); // CC-OFF(G.NAM.03-CPP) project code style +}; + +using DeclarationType = std::shared_ptr; + +class DeclarationCache final { + struct Tag {}; + +public: + inline static DeclarationType const ABSENT {}; + + DeclarationCache() = delete; + ~DeclarationCache(); + + NO_COPY_SEMANTIC(DeclarationCache); + NO_MOVE_SEMANTIC(DeclarationCache); + + explicit DeclarationCache(Tag &&tag); + + static DeclarationCache &Instance(); + + void ClearAll() noexcept; + + void RemoveDeclaration(std::string const &fileName) noexcept; + + DeclarationType GetDeclaration(std::string const &fileName) const noexcept; + + DeclarationType AddDeclaration(std::string fileName, DeclarationType decl); + +private: + inline static std::unique_ptr globalDeclarationCache_ = nullptr; + + std::unordered_map declarations_ {}; + + // Synchronization object to control access to cached data: + mutable ReadWriteSpinMutex dataGuard_ {}; +}; + +} // namespace ark::es2panda::parser + +#endif /* ES2PANDA_PDECLARATION_CACHE_H */ diff --git a/ets2panda/test/unit/union_normalisation_test.h b/ets2panda/test/unit/union_normalisation_test.h index 36b345f6c3..7b999d5620 100644 --- a/ets2panda/test/unit/union_normalisation_test.h +++ b/ets2panda/test/unit/union_normalisation_test.h @@ -32,7 +32,12 @@ public: { } - ~UnionNormalizationTest() override = default; + ~UnionNormalizationTest() override + { + if (publicContext_->phaseManager != nullptr) { + delete publicContext_->phaseManager; + } + } static void SetUpTestCase() { diff --git a/ets2panda/test/utils/ast_verifier_test.cpp b/ets2panda/test/utils/ast_verifier_test.cpp index 2175041ca7..8a59940bad 100644 --- a/ets2panda/test/utils/ast_verifier_test.cpp +++ b/ets2panda/test/utils/ast_verifier_test.cpp @@ -32,9 +32,17 @@ AstVerifierTest::AstVerifierTest() AstVerifierTest::~AstVerifierTest() { + if (phaseManager_ != nullptr) { + delete phaseManager_; + phaseManager_ = nullptr; + } + if (allocator_ != nullptr) { + delete allocator_; + allocator_ = nullptr; + } ASSERT(ctx_ == nullptr); impl_->MemFinalize(); impl_->DestroyConfig(cfg_); } -} // namespace test::utils \ No newline at end of file +} // namespace test::utils diff --git a/ets2panda/test/utils/ast_verifier_test.h b/ets2panda/test/utils/ast_verifier_test.h index 0d4d9fd955..46d307067a 100644 --- a/ets2panda/test/utils/ast_verifier_test.h +++ b/ets2panda/test/utils/ast_verifier_test.h @@ -206,7 +206,7 @@ private: es2panda_Impl const *impl_ {}; es2panda_Config *cfg_ {}; es2panda_Context *ctx_ {}; - ark::ThreadSafeArenaAllocator *allocator_ {}; + ark::ThreadSafeArenaAllocator *allocator_; ark::es2panda::compiler::PhaseManager *phaseManager_; friend class ::LSPAPITests; diff --git a/ets2panda/test/utils/checker_test.h b/ets2panda/test/utils/checker_test.h index 69f1fbdee0..62c2f7bc64 100644 --- a/ets2panda/test/utils/checker_test.h +++ b/ets2panda/test/utils/checker_test.h @@ -50,7 +50,14 @@ public: checker_(allocator_.get(), diagnosticEngine_) { } - ~CheckerTest() override = default; + + ~CheckerTest() override + { + if (publicContext_->phaseManager != nullptr) { + delete publicContext_->phaseManager; + } + } + static void SetUpTestCase() { ark::mem::MemConfig::Initialize(0, 0, ark::es2panda::COMPILER_SIZE, 0, 0, 0); @@ -146,7 +153,7 @@ public: varbinder->SetContext(publicContext_.get()); auto emitter = Emitter(publicContext_.get()); - auto phaseManager = compiler_alias::PhaseManager(publicContext_.get(), unit.ext, allocator_.get()); + auto phaseManager = new compiler_alias::PhaseManager(publicContext_.get(), unit.ext, allocator_.get()); auto config = plib_alias::ConfigImpl {}; publicContext_->config = &config; @@ -160,7 +167,7 @@ public: publicContext_->PushAnalyzer(publicContext_->GetChecker()->GetAnalyzer()); publicContext_->emitter = &emitter; publicContext_->diagnosticEngine = &diagnosticEngine_; - publicContext_->phaseManager = &phaseManager; + publicContext_->phaseManager = phaseManager; publicContext_->GetChecker()->Initialize(varbinder); parser.ParseScript(unit.input, unit.options.GetCompilationMode() == ark::es2panda::CompilationMode::GEN_STD_LIB); @@ -201,7 +208,7 @@ public: varbinder->SetContext(publicContext_.get()); auto emitter = Emitter(publicContext_.get()); - auto phaseManager = compiler_alias::PhaseManager(publicContext_.get(), unit.ext, allocator_.get()); + auto phaseManager = new compiler_alias::PhaseManager(publicContext_.get(), unit.ext, allocator_.get()); auto config = plib_alias::ConfigImpl {}; publicContext_->config = &config; @@ -215,7 +222,7 @@ public: publicContext_->PushAnalyzer(publicContext_->GetChecker()->GetAnalyzer()); publicContext_->emitter = &emitter; publicContext_->diagnosticEngine = &diagnosticEngine_; - publicContext_->phaseManager = &phaseManager; + publicContext_->phaseManager = phaseManager; publicContext_->GetChecker()->Initialize(varbinder); parser.ParseScript(unit.input, unit.options.GetCompilationMode() == ark::es2panda::CompilationMode::GEN_STD_LIB); diff --git a/ets2panda/util/importPathManager.cpp b/ets2panda/util/importPathManager.cpp index a22a321bea..43f869cdf6 100644 --- a/ets2panda/util/importPathManager.cpp +++ b/ets2panda/util/importPathManager.cpp @@ -26,7 +26,6 @@ #include "ir/expressions/literals/stringLiteral.h" #include "abc2program_driver.h" -#include "checker/types/signature.h" #include "compiler/lowering/ets/declGenPhase.h" #include "libpandabase/utils/logger.h" @@ -73,10 +72,10 @@ void ImportPathManager::ProcessExternalLibraryImport(ImportMetadata &importData) importData.declPath = externalModuleImportData.Path(); // process .d.ets "path" in "dependencies" - // process emptry "path" in dependencies, since in interop we allow imports without typecheck - if (!Helpers::EndsWith(std::string(externalModuleImportData.Path()), ".abc")) { + // process empty "path" in dependencies, since in interop we allow imports without typecheck + if (!Helpers::EndsWith(externalModuleImportData.Path(), ".abc")) { importData.importFlags |= ImportFlags::EXTERNAL_SOURCE_IMPORT; - importData.ohmUrl.assign(externalModuleImportData.OhmUrl(), externalModuleImportData.OhmUrl().size()); + importData.ohmUrl = externalModuleImportData.OhmUrl(); return; } @@ -101,15 +100,15 @@ void ImportPathManager::ProcessExternalLibraryImport(ImportMetadata &importData) ES2PANDA_ASSERT(Helpers::EndsWith(etsGlobalRecord->second.name, etsGlobalSuffix)); auto moduleName = etsGlobalRecord->second.name.substr(0, etsGlobalRecord->second.name.size() - etsGlobalSuffix.size()); - importData.ohmUrl = moduleName; + importData.ohmUrl = util::UString(moduleName, allocator_).View().Utf8(); auto annotations = etsGlobalRecord->second.metadata->GetAnnotations(); auto moduleDeclarationAnno = std::find_if(annotations.begin(), annotations.end(), [](auto &anno) { return anno.GetName() == compiler::DeclGenPhase::MODULE_DECLARATION_ANNOTATION; }); ES2PANDA_ASSERT(moduleDeclarationAnno != annotations.end()); - util::UString declText {moduleDeclarationAnno->GetElements()[0].GetValue()->GetAsScalar()->GetValue(), - allocator_}; + auto declText = util::UString( + moduleDeclarationAnno->GetElements()[0].GetValue()->GetAsScalar()->GetValue(), allocator_); importData.declText = declText.View().Utf8(); } @@ -369,10 +368,10 @@ void ImportPathManager::AddToParseList(const ImportMetadata &importMetadata) } } -void ImportPathManager::MarkAsParsed(StringView path) +void ImportPathManager::MarkAsParsed(std::string_view const path) noexcept { for (auto &parseInfo : parseList_) { - if (parseInfo.importData.resolvedSource == path.Utf8()) { + if (parseInfo.importData.resolvedSource == path) { parseInfo.isParsed = true; return; } @@ -549,7 +548,7 @@ util::StringView ImportPathManager::FormModuleName(const util::Path &path) } if (!parseList_.empty() && parseList_[0].importData.IsExternalBinaryImport()) { - return util::UString(parseList_[0].importData.ohmUrl, allocator_).View(); + return util::StringView(parseList_[0].importData.ohmUrl); } if (arktsConfig_->Package().empty() && !arktsConfig_->UseUrl()) { diff --git a/ets2panda/util/importPathManager.h b/ets2panda/util/importPathManager.h index 02273bf0ec..b2fea71b40 100644 --- a/ets2panda/util/importPathManager.h +++ b/ets2panda/util/importPathManager.h @@ -83,7 +83,7 @@ public: Language::Id lang {Language::Id::COUNT}; std::string_view resolvedSource {}; std::string_view declPath {}; - std::string ohmUrl {}; + std::string_view ohmUrl {}; std::string_view declText {}; // NOLINTEND(misc-non-private-member-variables-in-classes) @@ -158,7 +158,7 @@ public: // API version for resolving paths. Kept only for API compatibility. Doesn't support 'dependencies'. util::StringView ResolvePathAPI(StringView curModulePath, ir::StringLiteral *importPath) const; - void MarkAsParsed(StringView path); + void MarkAsParsed(std::string_view path) noexcept; util::StringView FormRelativePath(const util::Path &path); std::shared_ptr ArkTSConfig() const { -- Gitee