diff --git a/ets2panda/test/ast/parser/ets/import_tests/index/file.ets b/ets2panda/test/ast/parser/ets/import_tests/index/file.ets new file mode 100644 index 0000000000000000000000000000000000000000..bc554cdbef44186eec3a761615798fdb8aeb43d3 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/index/file.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { className } from "./folder/index" + +/* @@? 16:8 Error TypeError: Incorrect export 'className' */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/index/file_2.ets b/ets2panda/test/ast/parser/ets/import_tests/index/file_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..8960e15e51cb4f3bc713bfa19cbd67e9622e208e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/index/file_2.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { foo } from "./folder/index" + +/* @@? 16:8 Error TypeError: Ambiguous re-export of 'foo' exported from multiple sources. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/index/folder/foo.ets b/ets2panda/test/ast/parser/ets/import_tests/index/folder/foo.ets new file mode 100644 index 0000000000000000000000000000000000000000..98deb880f7c0c6519df87b46f08fc1dd35495c42 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/index/folder/foo.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function foo(){ + +} diff --git a/ets2panda/test/ast/parser/ets/import_tests/index/folder/index.ets b/ets2panda/test/ast/parser/ets/import_tests/index/folder/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb70633cb9faa5f6b37e39508844ce4e8749e99c --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/index/folder/index.ets @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from "./reflection" +export * from "./foo" diff --git a/ets2panda/test/ast/parser/ets/import_tests/index/folder/reflection.ets b/ets2panda/test/ast/parser/ets/import_tests/index/folder/reflection.ets new file mode 100644 index 0000000000000000000000000000000000000000..21181a5764de7e822f957b888803c2fb0284af80 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/index/folder/reflection.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { className } from "./ts-reflection" +export function lcClassName() { + return className(); +} + +export function foo(){ + +} diff --git a/ets2panda/test/ast/parser/ets/import_tests/index/folder/ts-reflection.ets b/ets2panda/test/ast/parser/ets/import_tests/index/folder/ts-reflection.ets new file mode 100644 index 0000000000000000000000000000000000000000..1c80594c7f8306c7bac73f781e86499a060c0e32 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/index/folder/ts-reflection.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function className(): string { + return "return"; +} diff --git a/ets2panda/test/ast/parser/ets/re_export/import_12.ets b/ets2panda/test/ast/parser/ets/re_export/import_12.ets index 9407cba8c70ed560e6a304360152eba959167fbf..d3f60b842087163090031669c318e1268e20cfd3 100644 --- a/ets2panda/test/ast/parser/ets/re_export/import_12.ets +++ b/ets2panda/test/ast/parser/ets/re_export/import_12.ets @@ -13,10 +13,10 @@ * limitations under the License. */ -import {foo} from "./re_export_7" +/* @@ label */import {foo} from "./re_export_7" function main() : void { } -// NOTE: ttamas - Duplication check disabled +/* @@@ label Error TypeError: Ambiguous re-export of 'foo' exported from multiple sources. */ diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 265d476e7abbe720324265509134e7ebbf535d40..8625f8ac84cff699d5d9ef862a9466012ebf8689 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -89,6 +89,10 @@ semantic: id: 126 message: "Reference to {} is ambiguous" +- name: AMBIGUOUS_REEXPORT + id: 402 + message: "Ambiguous re-export of '{}' exported from multiple sources." + - name: AMBIGUOUS_REFERENCE id: 61 message: "Ambiguous reference to '{}'" diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 1e7d1b087eecfc27cca8ca77be653403d47ba63d..49630c900f2440cc8c04bb8d18ed12158a932fbb 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -791,11 +791,24 @@ Variable *ETSBinder::FindImportSpecifiersVariable(const util::StringView &import return foundVar->second; } -static bool IsExportedVariable(varbinder::Variable *const var) +static bool IsExportedVariableInRightScope(varbinder::Variable *const var, ir::ETSImportDeclaration *const impDecl) { - return var != nullptr && - (var->Declaration()->Node()->IsExported() || var->Declaration()->Node()->IsDefaultExported() || - var->Declaration()->Node()->HasExportAlias()); + if (var == nullptr) { + std::cerr << " var false\n"; + return false; + } + + auto *prog = var->Declaration()->Node()->Program(); + if (prog == nullptr || impDecl == nullptr) { + std::cerr << "program nullptr - " << var->Declaration()->Name() << "\n"; + return (var->Declaration()->Node()->IsExported() || var->Declaration()->Node()->IsDefaultExported() || + var->Declaration()->Node()->HasExportAlias()); + } + + std::cerr << prog->AbsoluteName() << " - " << impDecl->ImportMetadata().resolvedSource << "\n"; + return (var->Declaration()->Node()->IsExported() || var->Declaration()->Node()->IsDefaultExported() || + var->Declaration()->Node()->HasExportAlias()) && + (prog->AbsoluteName().Is(impDecl->ImportMetadata().resolvedSource)); } std::pair ETSBinder::FindImportDeclInExports( @@ -889,6 +902,38 @@ std::pair ETSBinder::FindImportDeclIn ir::ETSImportDeclaration *implDecl = nullptr; ir::AstNode *specifier = nullptr; + std::cerr << ">> " << imported.Mutf8() << " start\n"; + + auto setImplDeclAndSpecifier = [&implDecl, &specifier, &import, &imported, this](ir::ETSImportDeclaration *decl, + ir::AstNode *spec) { + if (implDecl != nullptr && specifier != nullptr) { + std::cerr << "reExport error\n"; + ThrowError(import->Start(), diagnostic::AMBIGUOUS_REEXPORT, {imported.Mutf8()}); + } + implDecl = decl; + specifier = spec; + }; + + auto setImplDeclAndSpecifier2 = [&implDecl, &specifier, &import, &imported, this](ir::ETSImportDeclaration *decl, + ir::AstNode *spec) { + if (implDecl != nullptr && specifier != nullptr) { + std::cerr << "reExport error secund\n"; + ThrowError(import->Start(), diagnostic::AMBIGUOUS_REEXPORT, {imported.Mutf8()}); + } + implDecl = decl; + specifier = spec; + }; + + /*auto setImplDeclAndSpecifier3 = [&implDecl, &specifier, &import, &imported, this](ir::ETSImportDeclaration *decl, + ir::AstNode *spec) { + if (implDecl != nullptr && specifier != nullptr) { + std::cerr << "reExport error 3\n"; + ThrowError(import->Start(), diagnostic::AMBIGUOUS_REEXPORT, {imported.Mutf8()}); + } + implDecl = decl; + specifier = spec; + };*/ + for (auto item : ReExportImports()) { if (!ReexportPathMatchesImportPath(item, import)) { continue; @@ -901,8 +946,8 @@ std::pair ETSBinder::FindImportDeclIn })) { continue; } - implDecl = item->GetETSImportDeclarations(); - specifier = GetSpecifier(imported, implDecl); + setImplDeclAndSpecifier(item->GetETSImportDeclarations(), + GetSpecifier(imported, item->GetETSImportDeclarations())); } else { const auto records = GetExternalProgram(item->GetETSImportDeclarations()->ResolvedSource(), importPath); if (records.empty()) { @@ -910,9 +955,10 @@ std::pair ETSBinder::FindImportDeclIn } auto *const var = FindImportSpecifiersVariable(imported, records[0]->GlobalScope()->Bindings(), Span {records}); - if (IsExportedVariable(var)) { - implDecl = item->GetETSImportDeclarations(); - specifier = GetSpecifier(imported, implDecl); + if (IsExportedVariableInRightScope(var, item->GetETSImportDeclarations())) { + std::cerr << "secund true\n"; + setImplDeclAndSpecifier2(item->GetETSImportDeclarations(), + GetSpecifier(imported, item->GetETSImportDeclarations())); continue; } auto reExportImport = item->GetETSImportDeclarations(); @@ -920,11 +966,15 @@ std::pair ETSBinder::FindImportDeclIn auto [implDeclOrNullptr, localSpecifier] = FindImportDeclInExports(reExportImport, imported, reExportImportPath); if (implDeclOrNullptr != nullptr) { + std::cerr << "file: " << item->GetETSImportDeclarations()->ImportMetadata().resolvedSource << "\n"; + // setImplDeclAndSpecifier3(implDeclOrNullptr, GetSpecifier(imported, + // item->GetETSImportDeclarations())); implDecl = implDeclOrNullptr; - specifier = GetSpecifier(imported, implDecl); + specifier = GetSpecifier(imported, item->GetETSImportDeclarations()); } } } + std::cerr << ">> " << imported.Mutf8() << " end\n"; return std::make_pair(implDecl, specifier); }