From c9a6a240032f37e5b549793319047c399798a693 Mon Sep 17 00:00:00 2001 From: Robert Sipka Date: Mon, 5 Feb 2024 09:29:05 +0100 Subject: [PATCH] Refactoring path handling to improve maintainability and fixes some issues (part 1) Create a pathHandler class to resolve sources, handle module names, etc... Eliminated some redundant code parts Simplified path operations both the binder and parser code sections Resolved many inner issues Change-Id: I3ebbe28c47b5c1274c945029c7f319bfa1d1114f Signed-off-by: Robert Sipka --- ets2panda/BUILD.gn | 1 + ets2panda/CMakeLists.txt | 1 + ets2panda/checker/ETSAnalyzer.cpp | 17 +- ets2panda/checker/ets/dynamic.cpp | 10 +- ets2panda/checker/ets/helpers.cpp | 21 +- ets2panda/compiler/core/compilerImpl.cpp | 4 - ets2panda/ir/ets/etsImportDeclaration.h | 15 +- ets2panda/ir/ets/etsImportSource.h | 16 +- ets2panda/ir/ets/etsReExportDeclaration.h | 1 + ets2panda/parser/ETSparser.cpp | 454 +------- ets2panda/parser/ETSparser.h | 31 +- ets2panda/parser/program/program.h | 10 + .../check_exported_1-expected.txt | 2 +- .../check_exported_2-expected.txt | 2 +- .../check_exported_default_class-expected.txt | 2 +- .../import_tests/default_import-expected.txt | 2 +- .../import_tests/default_import2-expected.txt | 2 +- .../import_tests/diamond/test1-expected.txt | 4 +- .../import_tests/diamond/test2-expected.txt | 2 +- .../import_tests/diamond/test3-expected.txt | 2 +- .../duplicated/extdef-expected.txt | 2 +- .../duplicated/extusedef-expected.txt | 2 +- .../import_alias/import_alias_1-expected.txt | 2 +- .../import_alias/import_alias_2-expected.txt | 2 +- .../import_alias/import_alias_3-expected.txt | 2 +- .../import_alias/import_alias_4-expected.txt | 2 +- .../import_tests/import_all_2-expected.txt | 2 +- .../import_tests/import_all_3-expected.txt | 2 +- .../import_all_type_alias-expected.txt | 2 +- .../import_diff_paths-expected.txt | 4 +- .../import_interface_test-expected.txt | 4 +- .../import_interface_test_2-expected.txt | 2 +- .../import_tests/import_name_3-expected.txt | 2 +- .../import_tests/import_ts_file-expected.txt | 2 +- .../ets/import_tests/internals-expected.txt | 1006 ++++++++++++++++ .../parser/ets/import_tests/internals.ets | 21 + .../module1/src/export_file-expected.txt | 222 ++++ .../modules/module1/src/export_file.ets | 16 + .../module1/src/re_export_file-expected.txt | 153 +++ .../modules/module1/src/re_export_file.ets | 16 + .../module2/src/import_file-expected.txt | 225 ++++ .../modules/module2/src/import_file.ets | 16 + .../module2/src/re_export_file-expected.txt | 153 +++ .../modules/module2/src/re_export_file.ets | 16 + .../modules/test_lib2-expected.txt | 2 +- .../relative_import/Line-expected.txt | 2 +- .../relative_import/alias1-expected.txt | 2 +- .../ets/import_tests/repeat-expected.txt | 1012 +++++++++++++++++ .../test/parser/ets/import_tests/repeat.ets | 21 + .../folder1/file1-expected.txt | 2 +- .../folder2/file2-expected.txt | 2 +- .../ets/lambda_import_alias_1-2-expected.txt | 2 +- .../ets/lambda_import_alias_1-expected.txt | 2 +- .../parser/ets/re_export/import-expected.txt | 2 +- .../ets/re_export/import_2-expected.txt | 2 +- .../ets/re_export/import_3-expected.txt | 2 +- .../ets/re_export/import_4-expected.txt | 2 +- .../ets/re_export/import_5-expected.txt | 2 +- .../ets/re_export/import_6-expected.txt | 2 +- .../ets/re_export/import_7-expected.txt | 2 +- .../ets/re_export/import_8-expected.txt | 2 +- .../selective_export/import_1-expected.txt | 2 +- .../selective_export/import_2-expected.txt | 2 +- .../selective_export/import_3-expected.txt | 2 +- .../selective_export/import_4-expected.txt | 2 +- .../test/unit/union_normalization_test.cpp | 4 - ets2panda/util/declgenEts2Ts.cpp | 4 - ets2panda/util/path.cpp | 6 +- ets2panda/util/pathHandler.cpp | 279 +++++ ets2panda/util/pathHandler.h | 156 +++ ets2panda/varbinder/ETSBinder.cpp | 121 +- ets2panda/varbinder/ETSBinder.h | 27 +- 72 files changed, 3495 insertions(+), 648 deletions(-) create mode 100644 ets2panda/test/parser/ets/import_tests/internals-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/internals.ets create mode 100644 ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file.ets create mode 100644 ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file.ets create mode 100644 ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file.ets create mode 100644 ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file.ets create mode 100644 ets2panda/test/parser/ets/import_tests/repeat-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/repeat.ets create mode 100644 ets2panda/util/pathHandler.cpp create mode 100644 ets2panda/util/pathHandler.h diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index ad1b41851c..47cc740315 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -359,6 +359,7 @@ libes2panda_sources = [ "util/declgenEts2Ts.cpp", "util/helpers.cpp", "util/path.cpp", + "util/pathHandler.cpp", "util/plugin.cpp", "util/ustring.cpp", "varbinder/ASBinder.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 6a662e36a5..309b3e5762 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -437,6 +437,7 @@ set(ES2PANDA_LIB_SRC util/declgenEts2Ts.cpp util/helpers.cpp util/path.cpp + util/pathHandler.cpp util/ustring.cpp ) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 1b70952a61..4be4aa6215 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1870,7 +1870,7 @@ checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const } auto *importDecl = st->Parent()->AsETSImportDeclaration(); - auto importPath = importDecl->Source()->Str(); + auto importPath = importDecl->ResolvedSource()->Str(); if (importDecl->IsPureDynamic()) { auto *type = checker->GlobalBuiltinDynamicType(importDecl->Language()); @@ -1878,17 +1878,14 @@ checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const return type; } - std::string packageName = - (importDecl->Module() == nullptr) ? importPath.Mutf8() : importDecl->Module()->Str().Mutf8(); + auto [moduleName, isPackageModule] = checker->VarBinder()->AsETSBinder()->GetModuleNameFromSource(importPath); - std::replace(packageName.begin(), packageName.end(), '/', '.'); - util::UString packagePath(packageName, checker->Allocator()); - std::vector syntheticNames = checker->GetNameForSynteticObjectType(packagePath.View()); + std::vector syntheticNames = checker->GetNameForSynteticObjectType(moduleName); ASSERT(!syntheticNames.empty()); auto assemblerName = syntheticNames[0]; - if (importDecl->Module() != nullptr) { + if (!isPackageModule) { assemblerName = util::UString(assemblerName.Mutf8().append(".").append(compiler::Signatures::ETS_GLOBAL), checker->Allocator()) .View(); @@ -1910,11 +1907,7 @@ checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const lastObjectType = CreateSyntheticType(checker, syntheticName, lastObjectType, st->Local()->AsIdentifier()); } - checker->SetPropertiesForModuleObject( - lastObjectType, - (importDecl->Module() != nullptr) - ? util::UString(importPath.Mutf8() + importDecl->Module()->Str().Mutf8(), checker->Allocator()).View() - : importPath); + checker->SetPropertiesForModuleObject(lastObjectType, importPath); checker->SetrModuleObjectTsType(st->Local(), lastObjectType); return moduleObjectType; diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index c72d8eff47..0145ecb9b0 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -403,8 +403,14 @@ ir::ClassStaticBlock *ETSChecker::CreateDynamicModuleClassInitializer( ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); ArenaVector callParams(Allocator()->Adapter()); - callParams.push_back(import->ResolvedSource()); - + // Note(rsipka): this check could be avoided with appropriate language extensions + if (ark::os::file::File::IsRegularFile(import->ResolvedSource()->Str().Mutf8())) { + callParams.push_back(AllocNode( + util::UString(ark::os::RemoveExtension(import->ResolvedSource()->Str().Mutf8()), Allocator()) + .View())); + } else { + callParams.push_back(import->ResolvedSource()); + } auto *loadCall = AllocNode(callee, std::move(callParams), nullptr, false); auto *moduleClassId = diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 1e1874cb65..0e89b43e54 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -708,20 +708,6 @@ Type *ETSChecker::ResolveIdentifier(ir::Identifier *const ident) ValidateResolvedIdentifier(ident, resolved); - if (resolved->HasFlag(varbinder::VariableFlags::METHOD)) { - ASSERT(resolved->TsType()->IsETSFunctionType() && - !resolved->TsType()->AsETSFunctionType()->CallSignatures().empty()); - const auto *const funcType = resolved->TsType()->AsETSFunctionType(); - if (!funcType->CallSignatures().front()->Owner()->HasObjectFlag(checker::ETSObjectFlags::GLOBAL)) { - // In the case of function references, it is not enough to find the first method field and use it's function - // type, because at the position of the call we should be able to work with every possible signature, even - // with ones that came from base classes. - // NOTE: szd. find a better way than making a synthetic variable - resolved = funcType->CallSignatures().front()->Owner()->CreateSyntheticVarFromEverySignature( - ident->Name(), PropertySearchFlags::SEARCH_METHOD | PropertySearchFlags::SEARCH_IN_BASE); - } - } - ValidatePropertyAccess(resolved, Context().ContainingClass(), ident->Start()); SaveCapturedVariable(resolved, ident->Start()); @@ -1380,10 +1366,9 @@ void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjT auto *etsBinder = static_cast(VarBinder()); auto extRecords = etsBinder->GetGlobalRecordTable()->Program()->ExternalSources(); - auto res = [etsBinder, extRecords, importPath]() { - auto r = extRecords.find(importPath); - return r != extRecords.end() ? r : extRecords.find(etsBinder->GetResolvedImportPath(importPath)); - }(); + auto [name, isPackageModule] = etsBinder->GetModuleNameFromSource(importPath); + auto res = extRecords.find(name); + ASSERT(res != extRecords.end()); // Check imported properties before assigning them to module object res->second.front()->Ast()->Check(this); diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index adc123537c..803aff59e0 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -160,10 +160,6 @@ static pandasm::Program *CreateCompiler(const CompilationUnit &unit, const Phase &parser, &context); parser.ParseScript(unit.input, unit.options.compilationMode == CompilationMode::GEN_STD_LIB); - if constexpr (std::is_same_v && std::is_same_v) { - reinterpret_cast(varbinder)->FillResolvedImportPathes(parser.ResolvedParsedSourcesMap(), - &allocator); - } for (auto *phase : getPhases(unit.ext)) { if (!phase->Apply(&publicContext, &program)) { return nullptr; diff --git a/ets2panda/ir/ets/etsImportDeclaration.h b/ets2panda/ir/ets/etsImportDeclaration.h index 3d18c37f1a..18d29cb583 100644 --- a/ets2panda/ir/ets/etsImportDeclaration.h +++ b/ets2panda/ir/ets/etsImportDeclaration.h @@ -57,24 +57,19 @@ public: return assemblerName_; } - StringLiteral *ResolvedSource() + StringLiteral *Source() const { - return source_->ResolvedSource(); + return source_->Source(); } - const StringLiteral *ResolvedSource() const + StringLiteral *ResolvedSource() { return source_->ResolvedSource(); } - StringLiteral *Module() - { - return source_->Module(); - } - - const StringLiteral *Module() const + const StringLiteral *ResolvedSource() const { - return source_->Module(); + return source_->ResolvedSource(); } void Accept(ASTVisitorT *v) override diff --git a/ets2panda/ir/ets/etsImportSource.h b/ets2panda/ir/ets/etsImportSource.h index 3cc595bf2b..71a36c6537 100644 --- a/ets2panda/ir/ets/etsImportSource.h +++ b/ets2panda/ir/ets/etsImportSource.h @@ -26,9 +26,8 @@ namespace ark::es2panda::ir { class ImportSource { public: - explicit ImportSource(ir::StringLiteral *source, ir::StringLiteral *resolvedSource, Language lang, bool hasDecl, - ir::StringLiteral *module = nullptr) - : source_(source), resolvedSource_(resolvedSource), lang_(lang), hasDecl_(hasDecl), module_(module) + explicit ImportSource(ir::StringLiteral *source, ir::StringLiteral *resolvedSource, Language lang, bool hasDecl) + : source_(source), resolvedSource_(resolvedSource), lang_(lang), hasDecl_(hasDecl) { } NO_COPY_SEMANTIC(ImportSource); @@ -55,16 +54,6 @@ public: return resolvedSource_; } - const ir::StringLiteral *Module() const - { - return module_; - } - - ir::StringLiteral *Module() - { - return module_; - } - es2panda::Language Language() const { return lang_; @@ -80,7 +69,6 @@ private: ir::StringLiteral *resolvedSource_ {}; es2panda::Language lang_; bool hasDecl_; - ir::StringLiteral *module_ {}; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ets/etsReExportDeclaration.h b/ets2panda/ir/ets/etsReExportDeclaration.h index 8335142e9c..036cec101c 100644 --- a/ets2panda/ir/ets/etsReExportDeclaration.h +++ b/ets2panda/ir/ets/etsReExportDeclaration.h @@ -56,6 +56,7 @@ public: } private: + // NOTE(rsipka): this should use a singular name ETSImportDeclaration *etsImportDeclarations_; ArenaVector userPaths_; util::StringView programPath_; diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 7c90563385..21e3f1f920 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -122,24 +122,6 @@ #include "libpandabase/os/file.h" #include "generated/signatures.h" -#if defined PANDA_TARGET_MOBILE -#define USE_UNIX_SYSCALL -#endif - -#ifdef USE_UNIX_SYSCALL -#include -#include -#include -#else -#if __has_include() -#include -namespace fs = std::filesystem; -#elif __has_include() -#include -namespace fs = std::experimental::filesystem; -#endif -#endif - namespace ark::es2panda::parser { using namespace std::literals::string_literals; @@ -165,57 +147,14 @@ void ETSParser::ParseProgram(ScriptKind kind) ParseDefaultSources(); ParseETSGlobalScript(startLoc, statements); + GetProgram()->VarBinder()->AsETSBinder()->FillSourceList(this->GetPathes()); } void ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, ArenaVector &statements) { - auto paths = ParseImportDeclarations(statements); - - // clang-format off - auto removeParsedSources = [this](std::vector &items) { - items.erase(remove_if(begin(items), end(items), - [this](auto x) { - auto resolved = ResolveImportPath(x); - auto pathIter = - std::find_if(resolvedParsedSources_.begin(), resolvedParsedSources_.end(), - [resolved](const auto &p) { return p.second == resolved; }); - auto found = pathIter != resolvedParsedSources_.end(); - if (found) { - resolvedParsedSources_.emplace(x, resolved); - } - return found; - }), - end(items)); - - for (const auto &item : items) { - auto resolved = ResolveImportPath(item); - resolvedParsedSources_.emplace(item, resolved); - } - }; - // clang-format on - - removeParsedSources(paths); - - ParseSources(paths, false); - - if (!GetProgram()->VarBinder()->AsETSBinder()->ReExportImports().empty()) { - std::vector reExportPaths; - - for (auto reExport : GetProgram()->VarBinder()->AsETSBinder()->ReExportImports()) { - if (std::find(paths.begin(), paths.end(), reExport->GetProgramPath().Mutf8()) != paths.end()) { - auto path = - reExport->GetProgramPath().Mutf8().substr(0, reExport->GetProgramPath().Mutf8().find_last_of('/')); - for (auto item : reExport->GetUserPaths()) { - reExportPaths.push_back( - path + "/" + item.Mutf8().substr(item.Mutf8().find_first_of('/') + 1, item.Mutf8().length())); - } - } - } + ParseImportDeclarations(statements); - removeParsedSources(reExportPaths); - - ParseSources(reExportPaths, false); - } + ParseSources(false); ParseTopLevelDeclaration(statements); @@ -254,23 +193,13 @@ ArenaVector ETSParser::PrepareExternalGlobalClass([[maybe_unuse } auto &extSources = globalProgram_->ExternalSources(); - const util::StringView name = GetProgram()->SourceFileFolder(); - - auto res = extSources.end(); - if (!statements.empty()) { - res = extSources.find(name); - } else { - auto path = GetProgram()->SourceFileFolder().Mutf8() + ark::os::file::File::GetPathDelim().at(0) + - GetProgram()->GetPackageName().Mutf8(); - auto resolved = ResolveImportPath(path); - resolvedParsedSources_.emplace(path, resolved); - GetProgram()->SetSource(GetProgram()->SourceCode(), GetProgram()->SourceFilePath(), - util::UString(resolved, Allocator()).View()); - } + const util::StringView name = statements.empty() ? GetProgram()->FileName() : GetProgram()->GetPackageName(); + ASSERT(!name.Empty()); + auto res = extSources.find(name); if (res == extSources.end()) { CreateGlobalClass(); - auto insRes = extSources.emplace(GetProgram()->SourceFileFolder(), Allocator()->Adapter()); + auto insRes = extSources.emplace(name, Allocator()->Adapter()); insRes.first->second.push_back(GetProgram()); } else { res->second.push_back(GetProgram()); @@ -282,84 +211,6 @@ ArenaVector ETSParser::PrepareExternalGlobalClass([[maybe_unuse return statements; } -static bool IsCompitableExtension(const std::string &extension) -{ - return extension == ".ets" || extension == ".ts"; -} - -std::vector ETSParser::UnixApiDefaultSources([[maybe_unused]] const std::vector &stdlib) -{ - std::vector paths; -#ifdef USE_UNIX_SYSCALL - for (auto const &path : stdlib) { - auto resolvedPath = ResolveImportPath(path); - DIR *dir = opendir(resolvedPath.c_str()); - - if (dir == nullptr) { - ThrowSyntaxError({"Cannot open folder: ", resolvedPath}); - } - - struct dirent *entry; - std::set orderedFiles; - while ((entry = readdir(dir)) != nullptr) { - if (entry->d_type != DT_REG) { - continue; - } - - std::string fileName = entry->d_name; - std::string::size_type pos = fileName.find_last_of('.'); - if (pos == std::string::npos || !IsCompitableExtension(fileName.substr(pos))) { - continue; - } - - std::string filePath = path + "/" + entry->d_name; - - if (fileName == "Object.ets") { - paths.emplace(paths.begin(), filePath); - } else { - orderedFiles.emplace(filePath); - } - } - paths.insert(paths.end(), orderedFiles.begin(), orderedFiles.end()); - closedir(dir); - } -#endif - return paths; -} - -std::vector ETSParser::CollectDefaultSources() -{ - std::vector stdlib = {"std/core", "std/math", "std/containers", - "std/time", "std/interop/js", "escompat"}; - -#ifdef USE_UNIX_SYSCALL - return UnixApiDefaultSources(stdlib); -#else - std::vector paths; - for (auto const &path : stdlib) { - std::set orderedFiles; - for (auto const &entry : fs::directory_iterator(ResolveImportPath(path))) { - if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { - continue; - } - - std::string baseName = path; - std::size_t pos = entry.path().string().find_last_of(ark::os::file::File::GetPathDelim()); - - baseName.append(entry.path().string().substr(pos, entry.path().string().size())); - - if (entry.path().filename().string() == "Object.ets") { - paths.emplace(paths.begin(), baseName); - } else { - orderedFiles.emplace(baseName); - } - } - paths.insert(paths.end(), orderedFiles.begin(), orderedFiles.end()); - } - return paths; -#endif -} - ETSParser::ImportData ETSParser::GetImportData(const std::string &path) { auto &dynamicPaths = ArkTSConfig()->DynamicPaths(); @@ -384,205 +235,29 @@ ETSParser::ImportData ETSParser::GetImportData(const std::string &path) return {ToLanguage(Extension()), path, true}; } -std::string ETSParser::ResolveFullPathFromRelative(const std::string &path) -{ - char pathDelimiter = ark::os::file::File::GetPathDelim().at(0); - auto resolvedFp = GetProgram()->ResolvedFilePath().Mutf8(); - auto sourceFp = GetProgram()->SourceFileFolder().Mutf8(); - if (resolvedFp.empty()) { - auto fp = sourceFp + pathDelimiter + path; - return util::Helpers::IsRealPath(fp) ? fp : path; - } - auto fp = resolvedFp + pathDelimiter + path; - if (util::Helpers::IsRealPath(fp)) { - return fp; - } - if (path.find(sourceFp) == 0) { - return resolvedFp + pathDelimiter + path.substr(sourceFp.size()); - } - return path; -} - -std::string ETSParser::ResolveImportPath(const std::string &path) +void ETSParser::ParseSources(bool isExternal) { - char pathDelimiter = ark::os::file::File::GetPathDelim().at(0); - if (util::Helpers::IsRelativePath(path)) { - return util::Helpers::GetAbsPath(ResolveFullPathFromRelative(path)); - } - - std::string baseUrl; - // Resolve delimeter character to basePath. - if (path.find('/') == 0) { - baseUrl = ArkTSConfig()->BaseUrl(); - - baseUrl.append(path, 0, path.length()); - return baseUrl; - } - - auto &dynamicPaths = ArkTSConfig()->DynamicPaths(); - auto it = dynamicPaths.find(path); - if (it != dynamicPaths.cend() && !it->second.HasDecl()) { - return path; - } - - // Resolve the root part of the path. - // E.g. root part of std/math is std. - std::string::size_type pos = path.find('/'); - bool containsDelim = (pos != std::string::npos); - std::string rootPart = containsDelim ? path.substr(0, pos) : path; - - if (rootPart == "std" && !GetOptions().stdLib.empty()) { // Get std path from CLI if provided - baseUrl = GetOptions().stdLib + "/std"; - } else if (rootPart == "escompat" && !GetOptions().stdLib.empty()) { // Get escompat path from CLI if provided - baseUrl = GetOptions().stdLib + "/escompat"; - } else { - auto resolvedPath = ArkTSConfig()->ResolvePath(path); - if (resolvedPath.empty()) { - ThrowSyntaxError({"Can't find prefix for '", path, "' in ", ArkTSConfig()->ConfigPath()}); - } - return resolvedPath; - } - - if (containsDelim) { - baseUrl.append(1, pathDelimiter); - baseUrl.append(path, rootPart.length() + 1, path.length()); - } - - return baseUrl; -} - -std::tuple ETSParser::GetSourceRegularPath(const std::string &path, const std::string &resolvedPath) -{ - if (!ark::os::file::File::IsRegularFile(resolvedPath)) { - std::string importExtension = ".ets"; - - if (!ark::os::file::File::IsRegularFile(resolvedPath + importExtension)) { - importExtension = ".ts"; - - if (!ark::os::file::File::IsRegularFile(resolvedPath + importExtension)) { - ThrowSyntaxError("Incorrect path: " + resolvedPath); - } - } - return {path + importExtension, true}; - } - return {path, false}; -} - -void ETSParser::CollectUserSourcesFromIndex([[maybe_unused]] const std::string &path, - [[maybe_unused]] const std::string &resolvedPath, - [[maybe_unused]] std::vector &userPaths) -{ -#ifdef USE_UNIX_SYSCALL - DIR *dir = opendir(resolvedPath.c_str()); - bool isIndex = false; - std::set tmpPaths; - - if (dir == nullptr) { - ThrowSyntaxError({"Cannot open folder: ", resolvedPath}); - } - - struct dirent *entry; - while ((entry = readdir(dir)) != nullptr) { - if (entry->d_type != DT_REG) { - continue; - } + GetContext().Status() |= isExternal ? ParserStatus::IN_EXTERNAL : ParserStatus::IN_IMPORT; - std::string fileName = entry->d_name; - std::string::size_type pos = fileName.find_last_of('.'); - if (pos == std::string::npos || !IsCompitableExtension(fileName.substr(pos))) { + for (const auto &path : pathHandler_->GetParseList()) { + // NOTE(rsipka): could be handled nicer, but need to avoid recursive parses + if (pathHandler_->IsParsed(path)) { continue; } - - std::string filePath = path + "/" + entry->d_name; - - if (fileName == "index.ets" || fileName == "index.ts") { - userPaths.emplace_back(filePath); - isIndex = true; - break; - } else if (fileName == "Object.ets") { - userPaths.emplace(userPaths.begin(), filePath); - } else { - tmpPaths.insert(filePath); - } - } - - closedir(dir); - - if (!isIndex) { - userPaths.insert(userPaths.end(), tmpPaths.begin(), tmpPaths.end()); - } -#endif -} - -std::tuple, bool> ETSParser::CollectUserSources(const std::string &path) -{ - std::vector userPaths; - - const std::string resolvedPath = ResolveImportPath(path); - resolvedParsedSources_.emplace(path, resolvedPath); - const auto data = GetImportData(resolvedPath); - - if (!data.hasDecl) { - return {userPaths, false}; - } - - if (!ark::os::file::File::IsDirectory(resolvedPath)) { - std::string regularPath; - bool isModule = false; - std::tie(regularPath, isModule) = GetSourceRegularPath(path, resolvedPath); - userPaths.emplace_back(regularPath); - return {userPaths, isModule}; - } - -#ifdef USE_UNIX_SYSCALL - CollectUserSourcesFromIndex(path, resolvedPath, userPaths); -#else - if (fs::exists(resolvedPath + "/index.ets")) { - userPaths.emplace_back(path + "/index.ets"); - } else if (fs::exists(resolvedPath + "/index.ts")) { - userPaths.emplace_back(path + "/index.ts"); - } else { - std::set orderedFiles; - for (auto const &entry : fs::directory_iterator(resolvedPath)) { - if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { - continue; - } - - std::string baseName = path; - std::size_t pos = entry.path().string().find_last_of(ark::os::file::File::GetPathDelim()); - - baseName.append(entry.path().string().substr(pos, entry.path().string().size())); - orderedFiles.emplace(baseName); - } - userPaths.insert(userPaths.begin(), orderedFiles.begin(), orderedFiles.end()); - } -#endif - return {userPaths, false}; -} - -void ETSParser::ParseSources(const std::vector &paths, bool isExternal) -{ - GetContext().Status() |= isExternal ? ParserStatus::IN_EXTERNAL : ParserStatus::IN_IMPORT; - - const std::size_t pathCount = paths.size(); - for (std::size_t idx = 0; idx < pathCount; idx++) { - std::string resolvedPath = ResolveImportPath(paths[idx]); - resolvedParsedSources_.emplace(paths[idx], resolvedPath); - - const auto data = GetImportData(resolvedPath); + const auto data = GetImportData(path); if (!data.hasDecl) { continue; } - std::ifstream inputStream(resolvedPath.c_str()); + std::ifstream inputStream(path); - if (GetProgram()->SourceFilePath().Is(resolvedPath)) { + if (GetProgram()->SourceFilePath().Is(path)) { break; } if (inputStream.fail()) { - ThrowSyntaxError({"Failed to open file: ", resolvedPath.c_str()}); + ThrowSyntaxError({"Failed to open file: ", path}); } std::stringstream ss; @@ -590,7 +265,8 @@ void ETSParser::ParseSources(const std::vector &paths, bool isExter auto externalSource = ss.str(); auto currentLang = GetContext().SetLanguage(data.lang); - ParseSource({paths[idx].c_str(), externalSource.c_str(), resolvedPath.c_str(), false}); + pathHandler_->MarkAsParsed(path); + ParseSource({path, externalSource.c_str(), path, false}); GetContext().SetLanguage(currentLang); } @@ -611,7 +287,9 @@ void ETSParser::ParseDefaultSources() ParseImportDeclarations(statements); GetContext().Status() &= ~ParserStatus::IN_DEFAULT_IMPORTS; - ParseSources(CollectDefaultSources(), true); + pathHandler_->CollectDefaultSources(); + + ParseSources(true); } void ETSParser::ParseSource(const SourceFile &sourceFile) @@ -3087,10 +2765,7 @@ void ETSParser::ParseExport(lexer::SourcePosition startLoc) } // re-export directive - ir::ImportSource *reExportSource = nullptr; - std::vector userPaths; - - std::tie(reExportSource, userPaths) = ParseFromClause(true); + ir::ImportSource *reExportSource = ParseSourceFromClause(true); lexer::SourcePosition endLoc = reExportSource->Source()->End(); auto *reExportDeclaration = AllocNode(reExportSource, specifiers); @@ -3103,9 +2778,11 @@ void ETSParser::ParseExport(lexer::SourcePosition startLoc) ConsumeSemicolon(reExportDeclaration); - auto *reExport = Allocator()->New(reExportDeclaration, userPaths, + auto *reExport = Allocator()->New(reExportDeclaration, std::vector(), GetProgram()->SourceFilePath(), Allocator()); varbinder->AddReExportImport(reExport); + // parse reexport sources which were added in the previous parsing method + ParseSources(false); } ir::Statement *ETSParser::ParseFunctionStatement([[maybe_unused]] const StatementParsingFlags flags) @@ -3120,17 +2797,12 @@ void ETSParser::ParsePackageDeclaration(ArenaVector &statements if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_PACKAGE) { if (!IsETSModule() && GetProgram()->IsEntryPoint()) { + pathHandler_->SetModuleName(GetProgram()->AbsoluteName(), util::StringView(""), false); return; } - - auto baseName = GetProgram()->SourceFilePath().Utf8(); - baseName = baseName.substr(baseName.find_last_of(ark::os::file::File::GetPathDelim()) + 1); - const size_t idx = baseName.find_last_of('.'); - if (idx != std::string::npos) { - baseName = baseName.substr(0, idx); - } - - GetProgram()->SetPackageName(baseName); + pathHandler_->SetModuleName(GetProgram()->AbsoluteName(), GetProgram()->FileName(), false); + // NOTE(rsipka): setPackage should be eliminated from here, and should be reconsider its usage from program + GetProgram()->SetPackageName(GetProgram()->FileName()); return; } @@ -3145,14 +2817,15 @@ void ETSParser::ParsePackageDeclaration(ArenaVector &statements ConsumeSemicolon(packageDeclaration); statements.push_back(packageDeclaration); - if (name->IsIdentifier()) { - GetProgram()->SetPackageName(name->AsIdentifier()->Name()); - } else { - GetProgram()->SetPackageName(name->AsTSQualifiedName()->ToString(Allocator())); - } + auto packageName = + name->IsIdentifier() ? name->AsIdentifier()->Name() : name->AsTSQualifiedName()->ToString(Allocator()); + + GetProgram()->SetPackageName(packageName); + pathHandler_->SetModuleName(GetProgram()->AbsoluteName(), packageName, true); + pathHandler_->SetModuleName(GetProgram()->ResolvedFilePath(), packageName, true); } -std::tuple> ETSParser::ParseFromClause(bool requireFrom) +ir::ImportSource *ETSParser::ParseSourceFromClause(bool requireFrom) { if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_FROM) { if (requireFrom) { @@ -3167,52 +2840,21 @@ std::tuple> ETSParser::ParseFromCla } ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_STRING); - std::vector userPaths; - bool isModule = false; auto importPath = Lexer()->GetToken().Ident(); - auto resolvedImportPath = ResolveImportPath(importPath.Mutf8()); - resolvedParsedSources_.emplace(importPath.Mutf8(), resolvedImportPath); - - ir::StringLiteral *resolvedSource; - if (*importPath.Bytes() == '/') { - resolvedSource = AllocNode(util::UString(resolvedImportPath, Allocator()).View()); - } else { - resolvedSource = AllocNode(importPath); - } - - auto importData = GetImportData(resolvedImportPath); - - if ((GetContext().Status() & ParserStatus::IN_DEFAULT_IMPORTS) == 0) { - std::tie(userPaths, isModule) = CollectUserSources(importPath.Mutf8()); - } - - ir::StringLiteral *module = nullptr; - if (isModule) { - auto pos = importPath.Mutf8().find_last_of(ark::os::file::File::GetPathDelim()); - - util::UString baseName(importPath.Mutf8().substr(0, pos), Allocator()); - if (baseName.View().Is(".") || baseName.View().Is("..")) { - baseName.Append(ark::os::file::File::GetPathDelim()); - } - - module = AllocNode(util::UString(importPath.Mutf8().substr(pos + 1), Allocator()).View()); - importPath = baseName.View(); - } + auto resolvedImportPath = pathHandler_->AddPath(GetProgram()->AbsoluteName(), Lexer()->GetToken().Ident()); + auto *resolvedSource = AllocNode(resolvedImportPath); + auto importData = GetImportData(resolvedImportPath.Mutf8()); auto *source = AllocNode(importPath); source->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); - auto *importSource = - Allocator()->New(source, resolvedSource, importData.lang, importData.hasDecl, module); - return {importSource, userPaths}; + return Allocator()->New(source, resolvedSource, importData.lang, importData.hasDecl); } -std::vector ETSParser::ParseImportDeclarations(ArenaVector &statements) +void ETSParser::ParseImportDeclarations(ArenaVector &statements) { - std::vector allUserPaths; - std::vector userPaths; ArenaVector imports(Allocator()->Adapter()); while (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT) { @@ -3220,7 +2862,6 @@ std::vector ETSParser::ParseImportDeclarations(ArenaVectorNextToken(); // eat import ArenaVector specifiers(Allocator()->Adapter()); - ir::ImportSource *importSource = nullptr; if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { ParseNameSpaceSpecifier(&specifiers); @@ -3230,9 +2871,8 @@ std::vector ETSParser::ParseImportDeclarations(ArenaVectorSource()->End(); auto *importDeclaration = AllocNode(importSource, std::move(specifiers)); importDeclaration->SetRange({startLoc, endLoc}); @@ -3253,11 +2893,6 @@ std::vector ETSParser::ParseImportDeclarations(ArenaVector(GetProgram()->VarBinder()) ->SetDefaultImports(std::move(imports)); // get rid of it } - - sort(allUserPaths.begin(), allUserPaths.end()); - allUserPaths.erase(unique(allUserPaths.begin(), allUserPaths.end()), allUserPaths.end()); - - return allUserPaths; } void ETSParser::ParseNamedSpecifiers(ArenaVector *specifiers, bool isExport) @@ -3793,9 +3428,9 @@ ir::Statement *ETSParser::ParseImportDeclaration([[maybe_unused]] StatementParsi ConsumeSemicolon(astNode->AsTSImportEqualsDeclaration()); return astNode->AsTSImportEqualsDeclaration(); } - std::tie(importSource, userPaths) = ParseFromClause(true); + importSource = ParseSourceFromClause(true); } else { - std::tie(importSource, userPaths) = ParseFromClause(false); + importSource = ParseSourceFromClause(false); } lexer::SourcePosition endLoc = importSource->Source()->End(); @@ -5185,4 +4820,3 @@ InnerSourceParser::~InnerSourceParser() parser_->GetProgram()->SetSource(savedSourceCode_, savedSourceFile_, savedSourceFilePath_); } } // namespace ark::es2panda::parser -#undef USE_UNIX_SYSCALL diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index e835291f8d..d42919ba80 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -19,6 +19,7 @@ #include #include "parserFlags.h" #include "util/arktsconfig.h" +#include "util/pathHandler.h" #include "TypedParser.h" namespace ark::es2panda::ir { @@ -43,6 +44,9 @@ public: ETSParser(Program *program, const CompilerOptions &options, ParserStatus status = ParserStatus::NO_OPTS) : TypedParser(program, options, status), globalProgram_(GetProgram()) { + pathHandler_ = std::make_unique(Allocator()); + pathHandler_->SetArkTsConfig(ArkTSConfig()); + pathHandler_->SetStdLib(GetOptions().stdLib); } ETSParser() = delete; @@ -56,6 +60,11 @@ public: return true; } + ArenaUnorderedMap GetPathes() const + { + return pathHandler_->GetPathes(); + } + // Methods to create AST node(s) from the specified string (part of valid ETS-code!) // NOTE: the correct initial scope should be entered BEFORE calling any of these methods, // and correct parent and, probably, variable set to the node(s) after obtaining @@ -124,21 +133,13 @@ private: static int NFTWCallBack(const char *fpath, const struct stat * /*unused*/, int tflag, struct FTW * /*unused*/); #endif void ParseTopLevelDeclaration(ArenaVector &statements); - std::vector UnixApiDefaultSources(const std::vector &stdlib); - std::vector CollectDefaultSources(); - void CollectUserSourcesFromIndex(const std::string &path, const std::string &resolvedPath, - std::vector &userPaths); - std::string ResolveImportPath(const std::string &path); - std::string ResolveFullPathFromRelative(const std::string &path); ImportData GetImportData(const std::string &path); - std::tuple, bool> CollectUserSources(const std::string &path); - std::tuple GetSourceRegularPath(const std::string &path, const std::string &resolvedPath); - void ParseSources(const std::vector &paths, bool isExternal = true); - std::tuple> ParseFromClause(bool requireFrom); + void ParseSources(bool isExternal = true); + ir::ImportSource *ParseSourceFromClause(bool requireFrom); void ParseNamedSpecifiers(ArenaVector *specifiers, bool isExport = false); void ParseNamedExportSpecifiers(ArenaVector *specifiers, bool defaultExport); void ParseUserSources(std::vector userParths); - std::vector ParseImportDeclarations(ArenaVector &statements); + void ParseImportDeclarations(ArenaVector &statements); void ParseDefaultSources(); void ParseSource(const SourceFile &sourceFile); void CreateGlobalClass(); @@ -376,16 +377,10 @@ private: friend class ExternalSourceParser; friend class InnerSourceParser; -public: - const std::unordered_map &ResolvedParsedSourcesMap() const - { - return resolvedParsedSources_; - } - private: parser::Program *globalProgram_; std::vector insertingNodes_ {}; - std::unordered_map resolvedParsedSources_; + std::unique_ptr pathHandler_ {nullptr}; }; class ExternalSourceParser { diff --git a/ets2panda/parser/program/program.h b/ets2panda/parser/program/program.h index dd1681d6f4..6aab494a73 100644 --- a/ets2panda/parser/program/program.h +++ b/ets2panda/parser/program/program.h @@ -109,6 +109,16 @@ public: return sourceFileFolder_; } + util::StringView FileName() const + { + return sourceFile_.GetFileName(); + } + + util::StringView AbsoluteName() const + { + return sourceFile_.GetAbsolutePath(); + } + util::StringView ResolvedFilePath() const { return resolvedFilePath_; diff --git a/ets2panda/test/parser/ets/import_tests/check_exported_1-expected.txt b/ets2panda/test/parser/ets/import_tests/check_exported_1-expected.txt index 26d1fd8247..f5ea1ce217 100644 --- a/ets2panda/test/parser/ets/import_tests/check_exported_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/check_exported_1-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests", + "value": "import_tests/check_exported_2", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/check_exported_2-expected.txt b/ets2panda/test/parser/ets/import_tests/check_exported_2-expected.txt index 38133b2390..fac7c3f4be 100644 --- a/ets2panda/test/parser/ets/import_tests/check_exported_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/check_exported_2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests", + "value": "import_tests/check_exported_3", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/check_exported_default_class-expected.txt b/ets2panda/test/parser/ets/import_tests/check_exported_default_class-expected.txt index b91e824038..cf5d150156 100644 --- a/ets2panda/test/parser/ets/import_tests/check_exported_default_class-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/check_exported_default_class-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests/modules", + "value": "import_tests/modules/class_default_module", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/default_import-expected.txt b/ets2panda/test/parser/ets/import_tests/default_import-expected.txt index 8252c9d7ce..e45d7ab4d7 100644 --- a/ets2panda/test/parser/ets/import_tests/default_import-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/default_import-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests/modules", + "value": "import_tests/modules/default_export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/default_import2-expected.txt b/ets2panda/test/parser/ets/import_tests/default_import2-expected.txt index 0f61cf2901..1840a369e4 100644 --- a/ets2panda/test/parser/ets/import_tests/default_import2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/default_import2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests/modules", + "value": "import_tests/modules/missing_default_export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/diamond/test1-expected.txt b/ets2panda/test/parser/ets/import_tests/diamond/test1-expected.txt index 2993c35d60..6052f7d5ff 100644 --- a/ets2panda/test/parser/ets/import_tests/diamond/test1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/diamond/test1-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./test3", "loc": { "start": { "line": 16, @@ -77,7 +77,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./test2", "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/import_tests/diamond/test2-expected.txt b/ets2panda/test/parser/ets/import_tests/diamond/test2-expected.txt index 020e5e183a..8112eb8de8 100644 --- a/ets2panda/test/parser/ets/import_tests/diamond/test2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/diamond/test2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./test4", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/diamond/test3-expected.txt b/ets2panda/test/parser/ets/import_tests/diamond/test3-expected.txt index 41d64f40ed..433f4b32ea 100644 --- a/ets2panda/test/parser/ets/import_tests/diamond/test3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/diamond/test3-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./test4", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/duplicated/extdef-expected.txt b/ets2panda/test/parser/ets/import_tests/duplicated/extdef-expected.txt index c9698610cb..6167a42fec 100644 --- a/ets2panda/test/parser/ets/import_tests/duplicated/extdef-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/duplicated/extdef-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./classdef", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/duplicated/extusedef-expected.txt b/ets2panda/test/parser/ets/import_tests/duplicated/extusedef-expected.txt index cdb83d1a91..ae86bcd32c 100644 --- a/ets2panda/test/parser/ets/import_tests/duplicated/extusedef-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/duplicated/extusedef-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./extdef", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_1-expected.txt index 0c9678eb43..328f1e30a8 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_1-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_2-expected.txt index b93dcf3bac..dc7b8c9484 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_3-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_3-expected.txt index 87472d20e3..c68062b33a 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_3-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_4-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_4-expected.txt index 0f2f2abf89..4695e9911c 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_4-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_4-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_all_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_all_2-expected.txt index ab855e1e6c..279b5c3a73 100644 --- a/ets2panda/test/parser/ets/import_tests/import_all_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_all_2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests/modules", + "value": "import_tests/modules/default_export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_all_3-expected.txt b/ets2panda/test/parser/ets/import_tests/import_all_3-expected.txt index 29061158ab..d69502a277 100644 --- a/ets2panda/test/parser/ets/import_tests/import_all_3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_all_3-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests/modules", + "value": "import_tests/modules/default_export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt b/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt index 20deb523cd..24bbedcd1f 100644 --- a/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./export_type_alias", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_diff_paths-expected.txt b/ets2panda/test/parser/ets/import_tests/import_diff_paths-expected.txt index 36509b5515..04e0c4f94c 100644 --- a/ets2panda/test/parser/ets/import_tests/import_diff_paths-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_diff_paths-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./modules", + "value": "./modules/test_lib1", "loc": { "start": { "line": 16, @@ -77,7 +77,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./modules", + "value": "./modules/test_lib2", "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/import_tests/import_interface_test-expected.txt b/ets2panda/test/parser/ets/import_tests/import_interface_test-expected.txt index dcc9310ba5..5c9e6a2852 100644 --- a/ets2panda/test/parser/ets/import_tests/import_interface_test-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_interface_test-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./import_interface_test_2", "loc": { "start": { "line": 16, @@ -77,7 +77,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./import_interface_test_1", "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/import_tests/import_interface_test_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_interface_test_2-expected.txt index 016b5bf188..f69002cf70 100644 --- a/ets2panda/test/parser/ets/import_tests/import_interface_test_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_interface_test_2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./import_interface_test_1", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_name_3-expected.txt b/ets2panda/test/parser/ets/import_tests/import_name_3-expected.txt index 62dc8a7897..8ab7f0db0d 100644 --- a/ets2panda/test/parser/ets/import_tests/import_name_3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_name_3-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests/modules", + "value": "import_tests/modules/default_export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/import_ts_file-expected.txt b/ets2panda/test/parser/ets/import_tests/import_ts_file-expected.txt index 400aae202a..f1c34221ae 100644 --- a/ets2panda/test/parser/ets/import_tests/import_ts_file-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_ts_file-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "import_tests/modules", + "value": "import_tests/modules/typescript_file_import", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/internals-expected.txt b/ets2panda/test/parser/ets/import_tests/internals-expected.txt new file mode 100644 index 0000000000..af29ddcdd1 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/internals-expected.txt @@ -0,0 +1,1006 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "__memo_context_type", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 32 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Test", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "__context", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 22 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Test", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 25 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 25 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 25 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "declare": true, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "overloads": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + } + ], + "declare": true, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + } + ], + "declare": true, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "id": { + "type": "Identifier", + "name": "Test", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 22, + "column": 1 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/internals.ets b/ets2panda/test/parser/ets/import_tests/internals.ets new file mode 100644 index 0000000000..b55bb57ec7 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/internals.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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. + */ + +export type __memo_context_type = Test; +export type __context = Test; + +export interface Test { + name : string; +} diff --git a/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file-expected.txt new file mode 100644 index 0000000000..c89a3293c0 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file-expected.txt @@ -0,0 +1,222 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "num", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 17, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 17, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 17, + "column": 1 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file.ets b/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file.ets new file mode 100644 index 0000000000..0e4e596f2d --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 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. + */ + +export type num = number diff --git a/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file-expected.txt new file mode 100644 index 0000000000..3120da76ac --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file-expected.txt @@ -0,0 +1,153 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file.ets b/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file.ets new file mode 100644 index 0000000000..078e464304 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 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. + */ + +export {num} from "./export_file" diff --git a/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file-expected.txt new file mode 100644 index 0000000000..feefb20c22 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file-expected.txt @@ -0,0 +1,225 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./re_export_file", + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "num", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "imported": { + "type": "Identifier", + "name": "num", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file.ets b/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file.ets new file mode 100644 index 0000000000..e169b6ffdc --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 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 {num} from "./re_export_file" diff --git a/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file-expected.txt new file mode 100644 index 0000000000..3120da76ac --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file-expected.txt @@ -0,0 +1,153 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file.ets b/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file.ets new file mode 100644 index 0000000000..d4d8f815ca --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 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. + */ + +export {num} from "../../module1/src/re_export_file" diff --git a/ets2panda/test/parser/ets/import_tests/modules/test_lib2-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/test_lib2-expected.txt index 51e505772f..ea724972c8 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/test_lib2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/test_lib2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./test_lib1", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/relative_import/Line-expected.txt b/ets2panda/test/parser/ets/import_tests/relative_import/Line-expected.txt index e4fbb33d05..fd0ab85393 100644 --- a/ets2panda/test/parser/ets/import_tests/relative_import/Line-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/relative_import/Line-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./Point", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/relative_import/alias1-expected.txt b/ets2panda/test/parser/ets/import_tests/relative_import/alias1-expected.txt index 420064aeda..2d58b1d8fd 100644 --- a/ets2panda/test/parser/ets/import_tests/relative_import/alias1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/relative_import/alias1-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./alias2", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/repeat-expected.txt b/ets2panda/test/parser/ets/import_tests/repeat-expected.txt new file mode 100644 index 0000000000..ac5e0325b3 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/repeat-expected.txt @@ -0,0 +1,1012 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./internals", + "loc": { + "start": { + "line": 16, + "column": 37 + }, + "end": { + "line": 16, + "column": 50 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "__memo_context_type", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 29 + } + } + }, + "imported": { + "type": "Identifier", + "name": "__memo_context_type", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 29 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 51 + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "../import_tests/internals", + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 17, + "column": 54 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "__context", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "imported": { + "type": "Identifier", + "name": "__context", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 55 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "declare": true, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "overloads": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + } + ], + "declare": true, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + } + ], + "declare": true, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 16 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "id": { + "type": "Identifier", + "name": "Test", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 11 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/repeat.ets b/ets2panda/test/parser/ets/import_tests/repeat.ets new file mode 100644 index 0000000000..e04b10d705 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/repeat.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 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 { __memo_context_type } from "./internals"; +import { __context } from "../import_tests/internals"; + +interface Test { + name : string; +} diff --git a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder1/file1-expected.txt b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder1/file1-expected.txt index 8bdf712dcd..c81313289c 100644 --- a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder1/file1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder1/file1-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "../folder2", + "value": "../folder2/file2", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder2/file2-expected.txt b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder2/file2-expected.txt index d407c65f8a..5903ca994c 100644 --- a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder2/file2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder2/file2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "../folder3", + "value": "../folder3/file3", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt b/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt index fce52818b7..a84470483e 100644 --- a/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./lambda_import_alias_1-3", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt b/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt index fa725f4473..2d20fdf1fb 100644 --- a/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./lambda_import_alias_1-2", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/re_export/import-expected.txt b/ets2panda/test/parser/ets/re_export/import-expected.txt index 398ea0e512..76365e0577 100644 --- a/ets2panda/test/parser/ets/re_export/import-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./re_export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/re_export/import_2-expected.txt b/ets2panda/test/parser/ets/re_export/import_2-expected.txt index 6c96d8cb74..1a75bf6ad8 100644 --- a/ets2panda/test/parser/ets/re_export/import_2-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./re_export_2", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/re_export/import_3-expected.txt b/ets2panda/test/parser/ets/re_export/import_3-expected.txt index 90b1934eec..a86adcff2f 100644 --- a/ets2panda/test/parser/ets/re_export/import_3-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_3-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./re_export_3", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/re_export/import_4-expected.txt b/ets2panda/test/parser/ets/re_export/import_4-expected.txt index 7009eff8fe..abd5c3d1b7 100644 --- a/ets2panda/test/parser/ets/re_export/import_4-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_4-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./re_export_4", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/re_export/import_5-expected.txt b/ets2panda/test/parser/ets/re_export/import_5-expected.txt index 067ad6e2c9..a6bc554d84 100644 --- a/ets2panda/test/parser/ets/re_export/import_5-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_5-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./re_export_5", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/re_export/import_6-expected.txt b/ets2panda/test/parser/ets/re_export/import_6-expected.txt index be710cd392..2e1f1af0db 100644 --- a/ets2panda/test/parser/ets/re_export/import_6-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_6-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./folder", + "value": "./folder/re_export_6", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/re_export/import_7-expected.txt b/ets2panda/test/parser/ets/re_export/import_7-expected.txt index 9fdb5dec90..40f7893eb1 100644 --- a/ets2panda/test/parser/ets/re_export/import_7-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_7-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./re_export", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/re_export/import_8-expected.txt b/ets2panda/test/parser/ets/re_export/import_8-expected.txt index be710cd392..4d8d1f6639 100644 --- a/ets2panda/test/parser/ets/re_export/import_8-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_8-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./folder", + "value": "./folder/re_export_7", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/selective_export/import_1-expected.txt b/ets2panda/test/parser/ets/selective_export/import_1-expected.txt index 4d08cca3d2..1da65f2be0 100644 --- a/ets2panda/test/parser/ets/selective_export/import_1-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/import_1-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./selective_export_1", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/selective_export/import_2-expected.txt b/ets2panda/test/parser/ets/selective_export/import_2-expected.txt index 4d08cca3d2..9ca0096dd0 100644 --- a/ets2panda/test/parser/ets/selective_export/import_2-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/import_2-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./selective_export_2", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/selective_export/import_3-expected.txt b/ets2panda/test/parser/ets/selective_export/import_3-expected.txt index 4d08cca3d2..3988409545 100644 --- a/ets2panda/test/parser/ets/selective_export/import_3-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/import_3-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./selective_export_3", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/selective_export/import_4-expected.txt b/ets2panda/test/parser/ets/selective_export/import_4-expected.txt index 271570dc98..a35238d3d1 100644 --- a/ets2panda/test/parser/ets/selective_export/import_4-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/import_4-expected.txt @@ -5,7 +5,7 @@ "type": "ImportDeclaration", "source": { "type": "StringLiteral", - "value": "./", + "value": "./selective_export_4", "loc": { "start": { "line": 16, diff --git a/ets2panda/test/unit/union_normalization_test.cpp b/ets2panda/test/unit/union_normalization_test.cpp index 70e144ecd3..f98e4ba3ef 100644 --- a/ets2panda/test/unit/union_normalization_test.cpp +++ b/ets2panda/test/unit/union_normalization_test.cpp @@ -122,10 +122,6 @@ public: publicContext_->emitter = context.GetEmitter(); parser.ParseScript(unit.input, unit.options.compilationMode == CompilationMode::GEN_STD_LIB); - if constexpr (std::is_same_v && std::is_same_v) { - reinterpret_cast(varbinder)->FillResolvedImportPathes( - parser.ResolvedParsedSourcesMap(), allocator_.get()); - } for (auto *phase : getPhases) { if (!phase->Apply(publicContext_.get(), program)) { return; diff --git a/ets2panda/util/declgenEts2Ts.cpp b/ets2panda/util/declgenEts2Ts.cpp index a269aba84f..eee3b8d9c0 100644 --- a/ets2panda/util/declgenEts2Ts.cpp +++ b/ets2panda/util/declgenEts2Ts.cpp @@ -391,10 +391,6 @@ void TSDeclGen::GenImportDeclaration(const ir::ETSImportDeclaration *importDecla }); auto source = importDeclaration->Source()->Str().Mutf8(); - if (importDeclaration->Module() != nullptr) { - source += "/" + importDeclaration->Module()->Str().Mutf8(); - } - Out(" } from \"", source, "\";"); OutEndl(2U); } diff --git a/ets2panda/util/path.cpp b/ets2panda/util/path.cpp index 4c80dc17af..967459f353 100644 --- a/ets2panda/util/path.cpp +++ b/ets2panda/util/path.cpp @@ -37,11 +37,7 @@ void Path::Initializer(const std::string &path, ArenaAllocator *allocator) isRelative_ = true; } - if (isRelative_) { - absolutePath_ = util::UString(os::GetAbsolutePath(path_.Utf8()), allocator_).View(); - } else { - absolutePath_ = path_; - } + absolutePath_ = util::UString(os::GetAbsolutePath(path_.Utf8()), allocator_).View(); InitializeFileExtension(); InitializeFileName(); diff --git a/ets2panda/util/pathHandler.cpp b/ets2panda/util/pathHandler.cpp new file mode 100644 index 0000000000..71b1276696 --- /dev/null +++ b/ets2panda/util/pathHandler.cpp @@ -0,0 +1,279 @@ +/** + * Copyright (c) 2024 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 "pathHandler.h" +#include "libpandabase/os/filesystem.h" +#include + +#if defined PANDA_TARGET_MOBILE +#define USE_UNIX_SYSCALL +#endif + +#ifdef USE_UNIX_SYSCALL +#include +#include +#include +#else +#if __has_include() +#include +namespace fs = std::filesystem; +#elif __has_include() +#include +namespace fs = std::experimental::filesystem; +#endif +#endif + +namespace ark::es2panda::util { + +static bool IsCompitableExtension(const std::string &extension) +{ + return extension == ".ets" || extension == ".ts"; +} + +void PathHandler::UnixWalkThroughDirectory([[maybe_unused]] const StringView &directory) +{ +#ifdef USE_UNIX_SYSCALL + DIR *dir = opendir(directory.Mutf8().c_str()); + if (dir == nullptr) { + throw Error(ErrorType::GENERIC, "", "Cannot open folder: " + directory.Mutf8()); + } + + struct dirent *entry; + while ((entry = readdir(dir)) != nullptr) { + if (entry->d_type != DT_REG) { + continue; + } + + std::string fileName = entry->d_name; + std::string::size_type pos = fileName.find_last_of('.'); + if (pos == std::string::npos || !IsCompitableExtension(fileName.substr(pos))) { + continue; + } + + std::string filePath = directory.Mutf8() + "/" + entry->d_name; + StringView sourcePath = util::UString(filePath, allocator_).View(); + if (fileName == "Object.ets") { + pathes_.insert({sourcePath, ParseInfo(allocator_, true)}); + } else { + pathes_.insert({sourcePath, ParseInfo(allocator_)}); + } + } + + closedir(dir); +#endif +} + +StringView PathHandler::AddPath(const StringView &callerPath, const StringView &path) +{ + auto resolvedPath = ResolveSourcePath(callerPath, path); + if (!ark::os::file::File::IsDirectory(resolvedPath.Mutf8())) { + pathes_.insert({resolvedPath, ParseInfo(allocator_)}); + return resolvedPath; + } + + pathes_.insert({resolvedPath, ParseInfo(allocator_)}); + + bool hasIndexFile = false; + std::string indexFile = resolvedPath.Mutf8() + pathDelimiter_.data() + "index.ets"; + if (ark::os::file::File::IsRegularFile(indexFile)) { + hasIndexFile = true; + } else { + indexFile = resolvedPath.Mutf8() + pathDelimiter_.data() + "index.ts"; + if (ark::os::file::File::IsRegularFile(indexFile)) { + hasIndexFile = true; + } + } + + if (hasIndexFile) { + StringView indexFilePath = util::UString(indexFile, allocator_).View(); + pathes_.insert({indexFilePath, ParseInfo(allocator_)}); + return indexFilePath; + } + +#ifdef USE_UNIX_SYSCALL + UnixWalkThroughDirectory(resolvedPath); +#else + for (auto const &entry : fs::directory_iterator(resolvedPath.Mutf8())) { + if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { + continue; + } + + StringView sourcePath = util::UString(entry.path().string(), allocator_).View(); + if (entry.path().filename().string() == "Object.ets") { + pathes_.insert({sourcePath, ParseInfo(allocator_, true)}); + } else { + pathes_.insert({sourcePath, ParseInfo(allocator_)}); + } + } +#endif + return resolvedPath; +} + +void PathHandler::CollectDefaultSources() +{ + std::vector stdlib = {"std/core", "std/math", "std/containers", + "std/time", "std/interop/js", "escompat"}; + + for (auto const &path : stdlib) { + StringView callerPath = util::UString(allocator_).View(); + StringView stdlibPath = ResolveSourcePath(callerPath, util::UString(path, allocator_).View()); + pathes_.insert({stdlibPath, ParseInfo(allocator_)}); +#ifdef USE_UNIX_SYSCALL + UnixWalkThroughDirectory(stdlibPath); +#else + for (auto const &entry : fs::directory_iterator(stdlibPath.Mutf8())) { + if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { + continue; + } + + // NOTE(rsipka): seems to me a duplicated check, since it was already in pathes_ + StringView sourcePath = util::UString(entry.path().string(), allocator_).View(); + if (entry.path().filename().string() == "Object.ets") { + pathes_.insert({sourcePath, ParseInfo(allocator_, true)}); + } else { + pathes_.insert({sourcePath, ParseInfo(allocator_)}); + } + } +#endif + } +} + +std::vector PathHandler::GetParseList() const +{ + std::vector parseableSources; + for (const auto path : pathes_) { + if (!path.second.IsParsed() && !ark::os::file::File::IsDirectory(path.first.Mutf8())) { + // NOTE(rsipka): it should be handled in a better way + if (path.second.IsObjectfile()) { + parseableSources.emplace(parseableSources.begin(), path.first.Mutf8()); + } else { + parseableSources.emplace_back(path.first.Mutf8()); + } + } + } + return parseableSources; +} + +bool PathHandler::IsRelativePath(const StringView &path) const +{ + std::string currentDirReference = "."; + std::string parentDirReference = ".."; + + currentDirReference.append(pathDelimiter_); + parentDirReference.append(pathDelimiter_); + + return ((path.Mutf8().find(currentDirReference) == 0) || (path.Mutf8().find(parentDirReference) == 0)); +} + +StringView PathHandler::GetParentFolder(const StringView &path) const +{ + const size_t pos = path.Mutf8().find_last_of(pathDelimiter_); + if (pos != std::string::npos) { + return util::UString(path.Mutf8().substr(0, pos + 1), allocator_).View(); + } + + return util::UString(allocator_).View(); +} + +StringView PathHandler::AppendExtension(const StringView &path) const +{ + StringView realPath = GetRealPath(path); + if (ark::os::file::File::IsDirectory(realPath.Mutf8()) || ark::os::file::File::IsRegularFile(realPath.Mutf8())) { + return realPath; + } + + std::string importExtension = ".ets"; + if (!ark::os::file::File::IsRegularFile(path.Mutf8() + importExtension)) { + importExtension = ".ts"; + if (!ark::os::file::File::IsRegularFile(path.Mutf8() + importExtension)) { + // NOTE(rsipka): this check should be eliminated + auto &dynamicPaths = arktsConfig_->DynamicPaths(); + if (auto it = dynamicPaths.find(path.Mutf8()); it != dynamicPaths.cend()) { + return path; + } + + throw Error(ErrorType::GENERIC, "", "Not supported path: " + path.Mutf8()); + } + } + + return GetRealPath(util::UString(path.Mutf8().append(importExtension), allocator_).View()); +} + +StringView PathHandler::GetRealPath(const StringView &path) const +{ + const std::string realPath = ark::os::GetAbsolutePath(path.Mutf8()); + if (realPath.empty()) { + return path; + } + + if (realPath == path.Mutf8()) { + return path; + } + + return util::UString(realPath, allocator_).View(); +} + +StringView PathHandler::ResolveSourcePath(const StringView &callerPath, const StringView &path) const +{ + if (IsRelativePath(path)) { + const size_t pos = callerPath.Mutf8().find_last_of(pathDelimiter_); + ASSERT(pos != std::string::npos); + auto parentFolder = callerPath.Mutf8().substr(0, pos); + auto resolvedPath = util::UString(parentFolder, allocator_); + resolvedPath.Append(pathDelimiter_); + resolvedPath.Append(path.Mutf8()); + return AppendExtension(resolvedPath.View()); + } + + std::string baseUrl; + if (path.Mutf8().find('/') == 0) { + baseUrl = arktsConfig_->BaseUrl(); + baseUrl.append(path.Mutf8(), 0, path.Mutf8().length()); + return AppendExtension(util::UString(baseUrl, allocator_).View()); + } + + auto &dynamicPaths = arktsConfig_->DynamicPaths(); + if (auto it = dynamicPaths.find(path.Mutf8()); it != dynamicPaths.cend() && !it->second.HasDecl()) { + return AppendExtension(path); + } + + const size_t pos = path.Mutf8().find(pathDelimiter_); + bool containsDelim = (pos != std::string::npos); + auto rootPart = containsDelim ? path.Substr(0, pos) : path; + if (rootPart.Is("std") && !stdLib_.empty()) { // Get std path from CLI if provided + baseUrl = stdLib_ + "/std"; + } else if (rootPart.Is("escompat") && !stdLib_.empty()) { // Get escompat path from CLI if provided + baseUrl = stdLib_ + "/escompat"; + } else { + ASSERT(arktsConfig_ != nullptr); + auto resolvedPath = arktsConfig_->ResolvePath(path.Mutf8()); + if (resolvedPath.empty()) { + throw Error(ErrorType::GENERIC, "", + "Can't find prefix for '" + path.Mutf8() + "' in " + arktsConfig_->ConfigPath()); + } + + return AppendExtension(util::UString(resolvedPath, allocator_).View()); + } + + if (containsDelim) { + baseUrl.append(1, pathDelimiter_.at(0)); + baseUrl.append(path.Mutf8(), rootPart.Mutf8().length() + 1, path.Mutf8().length()); + } + + return util::UString(baseUrl, allocator_).View(); +} + +} // namespace ark::es2panda::util +#undef USE_UNIX_SYSCALL diff --git a/ets2panda/util/pathHandler.h b/ets2panda/util/pathHandler.h new file mode 100644 index 0000000000..2325659e16 --- /dev/null +++ b/ets2panda/util/pathHandler.h @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2024 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_UTIL_PATH_HANDLER_H +#define ES2PANDA_UTIL_PATH_HANDLER_H + +#include "util/arktsconfig.h" +#include "util/ustring.h" +#include +#include + +namespace ark::es2panda::util { + +class ParseInfo { +public: + explicit ParseInfo(ark::ArenaAllocator *allocator, bool isObjectFile = false) + : isObjectFile_(isObjectFile), isParsed_(false), moduleName_(allocator), isPackageModule_(false) + { + } + + ParseInfo() = delete; + + bool IsParsed() const + { + return isParsed_; + } + + void MarkAsParsed() + { + isParsed_ = true; + } + + StringView ModuleName() const + { + return moduleName_.View(); + } + + bool IsObjectfile() const + { + return isObjectFile_; + } + + bool IsPackageModule() const + { + return isPackageModule_; + } + + void SetModuleName(const StringView &moduleName, bool isPackageModule) + { + if (moduleName_.View().Empty()) { + moduleName_.Append(moduleName); + isPackageModule_ = isPackageModule; + } + } + +private: + bool isObjectFile_; + bool isParsed_; + util::UString moduleName_; + bool isPackageModule_; +}; + +class PathHandler { +public: + explicit PathHandler(ark::ArenaAllocator *allocator) : allocator_(allocator), pathes_(allocator->Adapter()) {} + + StringView AddPath(const StringView &callerPath, const StringView &path); + std::vector GetParseList() const; + void CollectDefaultSources(); + + void MarkAsParsed(const StringView &path) + { + auto it = pathes_.find(path); + if (it != pathes_.end()) { + it->second.MarkAsParsed(); + } + } + + bool IsParsed(const std::string &path) + { + auto pathView = util::UString(path, allocator_).View(); + auto it = pathes_.find(pathView); + if (it != pathes_.end()) { + return it->second.IsParsed(); + } + + return false; + } + + void MarkAsParsed(const std::string &path) + { + auto pathView = util::UString(path, allocator_).View(); + auto it = pathes_.find(pathView); + if (it != pathes_.end()) { + it->second.MarkAsParsed(); + } + } + + void SetModuleName(const StringView &path, const StringView &moduleName, bool isPackageModule) + { + auto it = pathes_.find(path); + if (it != pathes_.end()) { + it->second.SetModuleName(moduleName, isPackageModule); + } + } + + void SetStdLib(const std::string &stdLib) + { + stdLib_ = stdLib; + } + + void SetArkTsConfig(std::shared_ptr arktsConfig) + { + arktsConfig_ = std::move(arktsConfig); + } + + ArenaUnorderedMap &GetPathes() + { + return pathes_; + } + + NO_COPY_SEMANTIC(PathHandler); + NO_MOVE_SEMANTIC(PathHandler); + PathHandler() = delete; + ~PathHandler() = default; + +private: + bool IsRelativePath(const StringView &path) const; + StringView GetParentFolder(const StringView &path) const; + StringView ResolveSourcePath(const StringView &callerPath, const StringView &path) const; + StringView AppendExtension(const StringView &path) const; + StringView GetRealPath(const StringView &path) const; + void UnixWalkThroughDirectory(const StringView &directory); + + ArenaAllocator *allocator_; + ArenaUnorderedMap pathes_; + std::string stdLib_ = {}; + std::shared_ptr arktsConfig_ = {nullptr}; + std::string_view pathDelimiter_ = ark::os::file::File::GetPathDelim(); +}; + +} // namespace ark::es2panda::util + +#endif // ES2PANDA_UTIL_PATH_HANDLER_H diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index f54c6943f7..07677f86c0 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -496,33 +496,25 @@ bool ETSBinder::AddImportNamespaceSpecifiersToTopBindings(ir::AstNode *const spe std::unordered_set exportedNames; for (auto item : ReExportImports()) { - if (auto source = import->ResolvedSource()->Str().Mutf8(), - program = item->GetProgramPath().Mutf8().substr(0, item->GetProgramPath().Mutf8().find_last_of('.')); - source == program || (source + "/index") == program) { - // clang-format off - ir::StringLiteral dirName(util::UString(util::StringView(item->GetProgramPath().Mutf8().substr( - 0, item->GetProgramPath().Mutf8().find_last_of('/'))), - Allocator()) - .View()); - // clang-format on - dirName.SetStart(item->GetETSImportDeclarations()->Source()->Start()); - - for (auto it : item->GetETSImportDeclarations()->Specifiers()) { - if (it->IsImportNamespaceSpecifier() && - !specifier->AsImportNamespaceSpecifier()->Local()->Name().Empty()) { - std::cerr << "Warning: import with alias cannot be used with re-export\n"; - continue; - } - - AddSpecifiersToTopBindings(it, item->GetETSImportDeclarations(), - dirName.Str().Is(".") ? item->GetETSImportDeclarations()->Source() - : &dirName); - if (it->IsImportSpecifier() && - !exportedNames.insert(it->AsImportSpecifier()->Local()->Name().Mutf8()).second) { - ThrowError(import->Start(), "Ambiguous import \"" + - it->AsImportSpecifier()->Local()->Name().Mutf8() + - "\" has multiple matching exports"); - } + // NOTE(rsipka): this should be refactored or eliminated + if (auto source = import->ResolvedSource()->Str(), program = item->GetProgramPath(); + !source.Is(program.Mutf8())) { + continue; + } + + for (auto it : item->GetETSImportDeclarations()->Specifiers()) { + if (it->IsImportNamespaceSpecifier() && !specifier->AsImportNamespaceSpecifier()->Local()->Name().Empty()) { + std::cerr << "Warning: import with alias cannot be used with re-export\n"; + continue; + } + + AddSpecifiersToTopBindings(it, item->GetETSImportDeclarations(), + item->GetETSImportDeclarations()->Source()); + + if (it->IsImportSpecifier() && + !exportedNames.insert(it->AsImportSpecifier()->Local()->Name().Mutf8()).second) { + ThrowError(import->Start(), "Ambiguous import \"" + it->AsImportSpecifier()->Local()->Name().Mutf8() + + "\" has multiple matching exports"); } } } @@ -606,23 +598,15 @@ bool ETSBinder::AddImportSpecifiersToTopBindings(ir::AstNode *const specifier, if (var == nullptr) { for (auto item : ReExportImports()) { - if (auto source = import->ResolvedSource()->Str().Mutf8(), - program = item->GetProgramPath().Mutf8().substr(0, item->GetProgramPath().Mutf8().find_last_of('.')); - source == program || (source + "/index") == program) { - // clang-format off - ir::StringLiteral dirName(util::UString(util::StringView(item->GetProgramPath().Mutf8().substr( - 0, item->GetProgramPath().Mutf8().find_last_of('/'))), - Allocator()) - .View()); - // clang-format on - dirName.SetStart(item->GetETSImportDeclarations()->Source()->Start()); - - viewedReExport.push_back(item->GetETSImportDeclarations()); - AddSpecifiersToTopBindings( - specifier, item->GetETSImportDeclarations(), - dirName.Str().Is(".") ? item->GetETSImportDeclarations()->Source() : &dirName, viewedReExport); - return true; + if (auto source = import->ResolvedSource()->Str(), program = item->GetProgramPath(); + !source.Is(program.Mutf8())) { + continue; } + + viewedReExport.push_back(item->GetETSImportDeclarations()); + AddSpecifiersToTopBindings(specifier, item->GetETSImportDeclarations(), + item->GetETSImportDeclarations()->Source(), viewedReExport); + return true; } ThrowError(importPath->Start(), "Cannot find imported element " + imported.Mutf8()); } @@ -655,30 +639,14 @@ ArenaVector ETSBinder::GetExternalProgram(const util::StringV const ir::StringLiteral *importPath) { const auto &extRecords = globalRecordTable_.Program()->ExternalSources(); - auto recordRes = [this, extRecords, sourceName]() { - auto res = extRecords.find(sourceName); - if (res != extRecords.end()) { - return res; - } - if (res = extRecords.find({sourceName.Mutf8() + "/index"}); res != extRecords.end()) { - return res; - } - - res = extRecords.find(GetResolvedImportPath(sourceName)); - if (res == extRecords.end()) { - res = extRecords.find(GetResolvedImportPath({sourceName.Mutf8() + "/index"})); - } - - return res; - }(); - if (recordRes == extRecords.end()) { - ThrowError(importPath->Start(), "Cannot find import: " + std::string(sourceName)); + auto [name, _] = GetModuleNameFromSource(sourceName); + auto res = extRecords.find(name); + if (res == extRecords.end()) { + ThrowError(importPath->Start(), "Cannot find import: " + importPath->Str().Mutf8()); } - ASSERT(!recordRes->second.empty()); - - return recordRes->second; + return res->second; } void ETSBinder::AddSpecifiersToTopBindings(ir::AstNode *const specifier, const ir::ETSImportDeclaration *const import, @@ -692,30 +660,7 @@ void ETSBinder::AddSpecifiersToTopBindings(ir::AstNode *const specifier, const i return; } - const util::StringView sourceName = [import, importPath, this, &path]() { - if (import->Module() == nullptr) { - return importPath->Str(); - } - char pathDelimiter = ark::os::file::File::GetPathDelim().at(0); - auto strImportPath = importPath->Str().Mutf8(); - if (strImportPath.find(pathDelimiter) == (strImportPath.size() - 1)) { - return util::UString(strImportPath + import->Module()->Str().Mutf8(), Allocator()).View(); - } - - std::string importFilePath; - if (!import->Source()->Str().Is(path->Str().Mutf8()) && !import->Source()->Str().Empty() && - import->Source()->Str().Mutf8().substr(0, 1) == ".") { - importFilePath = - import->Source()->Str().Mutf8().substr(import->Source()->Str().Mutf8().find_first_not_of('.')); - if (importFilePath.size() == 1) { - importFilePath = ""; - } - } - - return util::UString(strImportPath + importFilePath + pathDelimiter + import->Module()->Str().Mutf8(), - Allocator()) - .View(); - }(); + const util::StringView sourceName = import->ResolvedSource()->Str(); auto record = GetExternalProgram(sourceName, importPath); const auto *const importProgram = record.front(); diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index b284f7fc2d..f6c24656cc 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -20,6 +20,7 @@ #include "varbinder/recordTable.h" #include "ir/ets/etsImportDeclaration.h" #include "ir/ets/etsReExportDeclaration.h" +#include "util/pathHandler.h" namespace ark::es2panda::varbinder { @@ -46,7 +47,7 @@ public: lambdaObjects_(Allocator()->Adapter()), dynamicImportVars_(Allocator()->Adapter()), importSpecifiers_(Allocator()->Adapter()), - resolvedImportPathesMap_(Allocator()->Adapter()) + sourceList_(Allocator()->Adapter()) { InitImplicitThisParam(); } @@ -202,24 +203,20 @@ public: defaultExport_ = defaultExport; } - const ArenaUnorderedMap &ResolvedImportPathesMap() const + void FillSourceList(const ArenaUnorderedMap &pathes) { - return resolvedImportPathesMap_; + for (const auto path : pathes) { + sourceList_.emplace(path.first, std::tuple(path.second.ModuleName(), + path.second.IsPackageModule())); + } } - const util::StringView &GetResolvedImportPath(const util::StringView &path) const + std::tuple GetModuleNameFromSource(const util::StringView &path) const { - ASSERT(resolvedImportPathesMap_.find(path) != resolvedImportPathesMap_.end()); - - return resolvedImportPathesMap_.find(path)->second; - } + auto it = sourceList_.find(path); + ASSERT(it != sourceList_.end()); - void FillResolvedImportPathes(const std::unordered_map &map, ArenaAllocator *allocator) - { - for (const auto &path : map) { - resolvedImportPathesMap_.emplace(util::UString(path.first, allocator).View(), - util::UString(path.second, allocator).View()); - } + return it->second; } bool IsDynamicModuleVariable(const Variable *var) const; @@ -262,7 +259,7 @@ private: DynamicImportVariables dynamicImportVars_; ir::Identifier *thisParam_ {}; ArenaVector> importSpecifiers_; - ArenaUnorderedMap resolvedImportPathesMap_; + ArenaUnorderedMap> sourceList_; ir::AstNode *defaultExport_ {}; }; -- Gitee