diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index 8ff6a03d759e633d44cc33280b0ec4d7bb52bff6..238a717544d41e12da2d801d25b52e0e85b0de90 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -410,7 +410,7 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & // NOTE(vpukhov): stdlib checks are to be removed - do not extend the existing logic if (globalProgram_->Kind() != parser::ScriptKind::STDLIB) { AddStaticBlockToClass(globalClass); - if (!util::Helpers::IsStdLib(globalProgram_)) { + if (!util::Helpers::IsStdLib(globalProgram_, parser_)) { auto initStatements = FormInitMethodStatements(moduleDependencies, std::move(immediateInitializers)); SetupGlobalMethods(std::move(initStatements)); } @@ -550,7 +550,7 @@ ArenaVector> GlobalClassHandler::FormInitStaticBloc ArenaVector> staticBlocks(allocator_->Adapter()); for (const auto &[p, ps] : initStatements) { ArenaVector statements(allocator_->Adapter()); - if (!util::Helpers::IsStdLib(globalProgram_) && moduleDependencies != nullptr) { + if (!util::Helpers::IsStdLib(globalProgram_, parser_) && moduleDependencies != nullptr) { FormDependentInitTriggers(statements, moduleDependencies); } statements.insert(statements.end(), ps.begin(), ps.end()); @@ -564,7 +564,7 @@ ArenaVector GlobalClassHandler::FormInitMethodStatements(const ArenaVector &&initStatements) { ArenaVector statements(allocator_->Adapter()); - if (!util::Helpers::IsStdLib(globalProgram_) && moduleDependencies != nullptr) { + if (!util::Helpers::IsStdLib(globalProgram_, parser_) && moduleDependencies != nullptr) { FormDependentInitTriggers(statements, moduleDependencies); } for (const auto &[p, ps] : initStatements) { diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 0e9894d3ff9049608f84ef1a124be46a353a58fc..575d8ff5f1bf4ada66337d05c83009c5f46d28d9 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -101,7 +101,7 @@ bool ETSParser::IsETSParser() const noexcept bool ETSParser::IsValidIdentifierName(const lexer::Token &token) const noexcept { - return !token.IsPredefinedType() || util::Helpers::IsStdLib(GetProgram()); + return !token.IsPredefinedType() || util::Helpers::IsStdLib(GetProgram(), this); } std::unique_ptr ETSParser::InitLexer(const SourceFile &sourceFile) @@ -840,7 +840,7 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() return nullptr; } - if (Lexer()->GetToken().IsReservedTypeName() && !util::Helpers::IsStdLib(GetProgram())) { + if (Lexer()->GetToken().IsReservedTypeName() && !util::Helpers::IsStdLib(GetProgram(), this)) { LogError(diagnostic::TYPE_ALIAS_INVALID_NAME, {TokenToString(Lexer()->GetToken().KeywordType())}); } diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index eeb70f15dca2474e58d457f68d2bdc94b0eabb04..6ad67fd77d82c4df6cc564665558a631dd5dd55d 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -442,7 +442,7 @@ private: bool IsExternal() const override { - return util::Helpers::IsStdLib(GetProgram()); + return util::Helpers::IsStdLib(GetProgram(), this); } // NOLINTNEXTLINE(google-default-arguments) diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index 1496bd4dbd3f668748262382d76dc9f0cc937ff2..0882541fc3e9fa278e637bb0d04e5fe8fa02405b 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -87,6 +87,66 @@ void ParserImpl::ParseProgram(ScriptKind kind) program_->SetAst(blockStmt); } +const std::optional> &ParserImpl::GetStdLibDirs() const +{ + return stdLibDirectories_; +} +void ParserImpl::SetStdLibDirs(ArenaUnorderedSet &dirs) const +{ + std::mutex mtx; + std::lock_guard lock(mtx); + stdLibDirectories_ = dirs; +} + +void ParserImpl::CollectStdLibPaths() const +{ + auto isDynamic = GetProgram()->IsDeclForDynamicStaticInterop(); + ArenaUnorderedSet stdLibDirs = ArenaUnorderedSet(Allocator()->Adapter()); + std::cout << std::endl << std::endl << std::endl << std::endl << std::endl; + std::cout << "GetOptions().GetStdlib(): " << GetOptions().GetStdlib() << std::endl; + std::cout << "GetOptions().GetStdlib(): " << GetOptions().GetStdlib() << std::endl; + std::cout << std::endl << std::endl << std::endl << std::endl << std::endl; + bool alreadyWritten = false; + for (auto const &stdLibPath : util::Helpers::StdLib()) { + std::optional resolvedPath; + if (!GetOptions().GetStdlib().empty()) { + std::cout << "set using --stdlib" << std::endl; + resolvedPath = std::string(ark::os::GetAbsolutePath(GetOptions().GetStdlib()) + + ark::os::file::File::GetPathDelim().at(0) + std::string(stdLibPath)); + } else if (GetOptions().ArkTSConfig() != nullptr) { + if (!alreadyWritten) { + std::cout << "set using arktsconfig" << std::endl; + std::cout << "BaseURL()" << GetOptions().ArkTSConfig()->BaseUrl() << std::endl; + std::cout << "ConfigPath()" << GetOptions().ArkTSConfig()->ConfigPath() << std::endl; + std::cout << "Files():" << std::endl; + for (auto f : GetOptions().ArkTSConfig()->Files()) { + std::cout << " - " << f << std::endl; + } + std::cout << "OutDir()" << GetOptions().ArkTSConfig()->OutDir() << std::endl; + std::cout << "RootDir()" << GetOptions().ArkTSConfig()->RootDir() << std::endl; + for (auto p : GetOptions().ArkTSConfig()->Paths()) { + std::cout << " - " << p.first << ": " << std::endl; + for (auto pp : p.second) { + std::cout << " - "<< pp << std::endl; + } + } + alreadyWritten = true; + } + resolvedPath = GetOptions().ArkTSConfig()->ResolvePath(std::string_view(stdLibPath), isDynamic); + } else { + std::cout << "I have no basepath for stdlib" << std::endl; + break; + } + stdLibDirs.insert(util::StringView(util::UString(ark::os::NormalizePath(*resolvedPath), Allocator()).View())); + } + std::cout << "---- these are the stdlib folders:" << std::endl; + for (auto d : stdLibDirs) { + std::cout << d << std::endl; + } + std::cout << std::endl << std::endl << std::endl << std::endl << std::endl; + SetStdLibDirs(stdLibDirs); +} + bool ParserImpl::InAmbientContext() { return (context_.Status() & ParserStatus::IN_AMBIENT_CONTEXT) != 0; diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index d0238cef36ff4b495b3e6d9895561b7308db3631..b1404dbd3bb5f4a9c015225b1cc53becd4e928de 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -222,6 +222,10 @@ public: void LogSyntaxError(std::string_view errorMessage, const lexer::SourcePosition &pos); void LogSyntaxError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos); + void CollectStdLibPaths() const; + const std::optional> &GetStdLibDirs() const; + void SetStdLibDirs(ArenaUnorderedSet &dirs) const; + protected: void LogParameterModifierError(ir::ModifierFlags status); // Error handling @@ -608,6 +612,7 @@ private: util::DiagnosticEngine &diagnosticEngine_; public_lib::Context *ctx_ {nullptr}; RecursiveContext recursiveCtx_; + mutable std::optional> stdLibDirectories_ {}; }; } // namespace ark::es2panda::parser diff --git a/ets2panda/parser/program/program.h b/ets2panda/parser/program/program.h index fbb24ddfd2e1089f694870eeeca6edd1bc22e76c..7097576a39e3fcdf77c872a737a15c274115802c 100644 --- a/ets2panda/parser/program/program.h +++ b/ets2panda/parser/program/program.h @@ -303,6 +303,16 @@ public: (FileName().Is("etsstdlib")); } + void SetIsInStdLib(bool isInStdLib) + { + isInStdLib_ = isInStdLib; + } + + std::optional GetIsInStdLib() + { + return isInStdLib_; + } + bool IsGenAbcForExternal() const; void SetGenAbcForExternalSources(bool genAbc = true) @@ -393,6 +403,7 @@ private: compiler::CFG *cfg_; ArenaVector functionScopes_; std::unordered_map> fileDependencies_; + std::optional isInStdLib_ {}; private: ArenaMap varbinders_; diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index fe9e9b5e32be1efb4419a93f0f1dad004cd8756d..516936db43e05cd0a08c5119b4219e9d32942f0b 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -768,23 +768,37 @@ bool Helpers::IsNumericGlobalBuiltIn(checker::Type *type, checker::ETSChecker *c CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalFloatBuiltinType()); } -bool Helpers::IsStdLib(const parser::Program *program) +bool Helpers::IsStdLib(parser::Program *program, const parser::ParserImpl *parser) { - // NOTE(rsipka): early check: if program is not in a package then it is not part of the stdlib either - if (!program->IsPackage()) { + if (program->GetIsInStdLib().has_value()) { + return program->GetIsInStdLib().value(); + } + + if (program->Extension() != ScriptExtension::ETS || !program->IsPackage()) { + program->SetIsInStdLib(false); + if (program->Extension() != ScriptExtension::ETS) { + std::cout << program->AbsoluteName() << ": not std lib because extension is not ETS" << std::endl; + } else if (!program->IsPackage()) { + std::cout << program->AbsoluteName() << ": not std lib because it is not a PACKAGE" << std::endl; + } return false; } - auto fileFolder = program->ModuleName().Mutf8(); - std::replace(fileFolder.begin(), fileFolder.end(), *compiler::Signatures::METHOD_SEPARATOR.begin(), - *compiler::Signatures::NAMESPACE_SEPARATOR.begin()); + if (!parser->GetStdLibDirs().has_value()) { + parser->CollectStdLibPaths(); + } - if (fileFolder == "std/math/consts") { - return true; + for (auto stdPath : *parser->GetStdLibDirs()) { + if (program->AbsoluteName().StartsWith(stdPath.Mutf8())) { + program->SetIsInStdLib(true); + return true; + } } - auto const &stdlib = StdLib(); - return std::count(stdlib.begin(), stdlib.end(), fileFolder) != 0; + program->SetIsInStdLib(false); + + std::cout << program->AbsoluteName() << ": not std lib because i could not find it in the STDDIRS" << std::endl; + return false; } checker::Type *Helpers::CheckReturnTypeOfCheck([[maybe_unused]] const ir::AstNode *const node, diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index c6ece8cab114fe9b0bfbd7e21bb0d11c78801da2..190798e7c06e036e6cf1de50a8ac8f17e689c7fb 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -203,7 +203,7 @@ public: static std::pair SplitSignature(std::string_view signature); static std::vector const &StdLib(); - static bool IsStdLib(const parser::Program *program); + static bool IsStdLib(parser::Program *program, const parser::ParserImpl *parser); [[nodiscard]] static checker::Type *CheckReturnTypeOfCheck([[maybe_unused]] const ir::AstNode *const node, checker::Type *const type); diff --git a/ets2panda/util/importPathManager.cpp b/ets2panda/util/importPathManager.cpp index a7f93fb25ed3037df329aea407d1c799953a7a5d..96906a27e1b883e8804ff22ecadeeeead868d90a 100644 --- a/ets2panda/util/importPathManager.cpp +++ b/ets2panda/util/importPathManager.cpp @@ -269,6 +269,7 @@ ImportPathManager::ResolvedPathRes ImportPathManager::ResolveAbsolutePath(const auto rootPart = containsDelim ? importPath.substr(0, pos) : importPath; if (!stdLib_.empty() && ((rootPart == "std") || (rootPart == "escompat"))) { // Get std or escompat path from CLI if provided + std::cout << "stdLib_ is NOT empty in ResolveAbsolutePath" << std::endl; auto baseUrl = std::string(GetRealPath(StringView(stdLib_))) + pathDelimiter_.at(0) + std::string(rootPart); if (containsDelim) { @@ -278,6 +279,7 @@ ImportPathManager::ResolvedPathRes ImportPathManager::ResolveAbsolutePath(const return {UString(baseUrl, allocator_).View().Utf8()}; } + std::cout << "stdLib_ is empty in ResolveAbsolutePath" << std::endl; ES2PANDA_ASSERT(arktsConfig_ != nullptr); auto resolvedPath = arktsConfig_->ResolvePath(importPath, isDynamic_); if (!resolvedPath) { diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 1e7d1b087eecfc27cca8ca77be653403d47ba63d..8ff17a8a5e82c736be5d4915c193237c189e1124 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -659,7 +659,7 @@ void ETSBinder::ImportAllForeignBindings(const varbinder::Scope::VariableMap &gl const varbinder::GlobalScope *const importGlobalScope, const ir::ETSImportDeclaration *const import) { - bool const isStdLib = util::Helpers::IsStdLib(Program()); + bool const isStdLib = util::Helpers::IsStdLib(Program(), GetContext()->parser->AsETSParser()); for (const auto [bindingName, var] : globalBindings) { if (!var->Declaration()->Node()->IsValidInCurrentPhase()) { @@ -946,7 +946,8 @@ bool ETSBinder::DetectNameConflict(const util::StringView localName, Variable *c } if (var->Declaration()->IsFunctionDecl() && otherVar->Declaration()->IsFunctionDecl()) { - AddOverloadFlag(Allocator(), util::Helpers::IsStdLib(Program()), var, otherVar); + AddOverloadFlag(Allocator(), util::Helpers::IsStdLib(Program(), GetContext()->parser->AsETSParser()), var, + otherVar); return true; } @@ -1552,7 +1553,7 @@ bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable auto variable = Program()->GlobalClassScope()->FindLocal(name, ResolveBindingOptions::ALL); - bool isStdLib = util::Helpers::IsStdLib(Program()); + bool isStdLib = util::Helpers::IsStdLib(Program(), GetContext()->parser); if (variable != nullptr && var != variable) { if (variable->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { AddOverloadFlag(Allocator(), isStdLib, var, variable);