From 13d2d41fec65633de12710ec637f71f9ef83c1b6 Mon Sep 17 00:00:00 2001 From: Tamas Toth Date: Tue, 22 Jul 2025 09:47:59 +0200 Subject: [PATCH] Ambiguous reExport for multiply-exported symbols Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICO0D8 Fixes #25457 internal issue Change-Id: I658d2a46b259c4325d6d11571a93a33a4346ef6e Signed-off-by: Tamas Toth --- ets2panda/scripts/arkui.properties | 2 +- .../parser/ets/import_tests/index/file.ets | 18 ++++++ .../ets/import_tests/index/folder/index.ets | 16 ++++++ .../import_tests/index/folder/reflection.ets | 19 +++++++ .../index/folder/ts-reflection.ets | 18 ++++++ .../ast/parser/ets/re_export/import_12.ets | 4 +- ets2panda/util/diagnostic/semantic.yaml | 4 ++ ets2panda/varbinder/ETSBinder.cpp | 56 +++++++++++++++---- 8 files changed, 123 insertions(+), 14 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/import_tests/index/file.ets create mode 100644 ets2panda/test/ast/parser/ets/import_tests/index/folder/index.ets create mode 100644 ets2panda/test/ast/parser/ets/import_tests/index/folder/reflection.ets create mode 100644 ets2panda/test/ast/parser/ets/import_tests/index/folder/ts-reflection.ets diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index daa4c0a040..4ac57c7ca3 100644 --- a/ets2panda/scripts/arkui.properties +++ b/ets2panda/scripts/arkui.properties @@ -1,3 +1,3 @@ ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git -ARKUI_DEV_BRANCH=panda_rev_10-remove-deprecated-ani-array-api +ARKUI_DEV_BRANCH=issue-25457 ARKUI_DEST=koala-sig 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 0000000000..bc554cdbef --- /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/folder/index.ets b/ets2panda/test/ast/parser/ets/import_tests/index/folder/index.ets new file mode 100644 index 0000000000..35c8ea00de --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/index/folder/index.ets @@ -0,0 +1,16 @@ +/* + * 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" 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 0000000000..30be17cf6e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/index/folder/reflection.ets @@ -0,0 +1,19 @@ +/* + * 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(); +} 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 0000000000..1c80594c7f --- /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 9407cba8c7..d3f60b8420 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 5b7a9bdbff..d52faee572 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 878296e704..23f402589a 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -790,11 +790,21 @@ 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 || impDecl == nullptr) { + return false; + } + + auto *prog = var->Declaration()->Node()->Program(); + if (prog == nullptr) { + return (var->Declaration()->Node()->IsExported() || var->Declaration()->Node()->IsDefaultExported() || + var->Declaration()->Node()->HasExportAlias()); + } + + return (var->Declaration()->Node()->IsExported() || var->Declaration()->Node()->IsDefaultExported() || + var->Declaration()->Node()->HasExportAlias()) && + (prog->AbsoluteName().Is(impDecl->ImportMetadata().resolvedSource)); } std::pair ETSBinder::FindImportDeclInExports( @@ -888,6 +898,16 @@ std::pair ETSBinder::FindImportDeclIn ir::ETSImportDeclaration *implDecl = nullptr; ir::AstNode *specifier = nullptr; + auto setImplDeclAndSpecifier = [&implDecl, &specifier, &import, &imported, this](ir::ETSImportDeclaration *decl, + ir::AstNode *spec) { + if (implDecl != nullptr && specifier != nullptr) { + std::cerr << "throw ERROR\n"; + ThrowError(import->Start(), diagnostic::AMBIGUOUS_REEXPORT, {imported.Mutf8()}); + } + implDecl = decl; + specifier = spec; + }; + for (auto item : ReExportImports()) { if (!ReexportPathMatchesImportPath(item, import)) { continue; @@ -900,8 +920,9 @@ std::pair ETSBinder::FindImportDeclIn })) { continue; } - implDecl = item->GetETSImportDeclarations(); - specifier = GetSpecifier(imported, implDecl); + std::cerr << "first\n"; + setImplDeclAndSpecifier(item->GetETSImportDeclarations(), + GetSpecifier(imported, item->GetETSImportDeclarations())); } else { const auto records = GetExternalProgram(item->GetETSImportDeclarations()->ResolvedSource(), importPath); if (records.empty()) { @@ -909,9 +930,16 @@ 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 << "second\n"; + if (var != nullptr && var->Declaration()->Node()->Program() == nullptr) { + std::cerr << " - nullptr\n"; + implDecl = item->GetETSImportDeclarations(); + specifier = GetSpecifier(imported, item->GetETSImportDeclarations()); + continue; + } + setImplDeclAndSpecifier(item->GetETSImportDeclarations(), + GetSpecifier(imported, item->GetETSImportDeclarations())); continue; } auto reExportImport = item->GetETSImportDeclarations(); @@ -919,8 +947,14 @@ std::pair ETSBinder::FindImportDeclIn auto [implDeclOrNullptr, localSpecifier] = FindImportDeclInExports(reExportImport, imported, reExportImportPath); if (implDeclOrNullptr != nullptr) { - implDecl = implDeclOrNullptr; - specifier = GetSpecifier(imported, implDecl); + std::cerr << "third\n"; + if (var != nullptr && var->Declaration()->Node()->Program() == nullptr) { + std::cerr << " - nullptr\n"; + implDecl = implDeclOrNullptr; + specifier = GetSpecifier(imported, item->GetETSImportDeclarations()); + continue; + } + setImplDeclAndSpecifier(implDeclOrNullptr, GetSpecifier(imported, item->GetETSImportDeclarations())); } } } -- Gitee