diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index ab87ed9b46aab0375ecb4a7396fca515aedbbab6..c5a3654de156e8c89d8722e9ea7cea5eb2fd53a4 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -372,6 +372,52 @@ static void CheckOverloadSameNameMethod(ETSChecker *const checker, ir::OverloadD } } +static void CheckOverloadFunctionInNamespace(ETSChecker *const checker, ir::OverloadDeclaration *const overloadDecl) +{ + if (!overloadDecl->IsFunctionOverloadDeclaration()) { + return; + } + + varbinder::Scope *overloadScope = nullptr; + if (overloadDecl->Id() && overloadDecl->Id()->Variable()) { + overloadScope = overloadDecl->Id()->Variable()->GetScope(); + } else { + overloadScope = checker->VarBinder()->GetScope(); + } + + for (auto *expr : overloadDecl->OverloadedList()) { + std::string tmpName; + std::string_view nameView; + + if (expr->IsMemberExpression()) { + auto *prop = expr->AsMemberExpression()->Property(); + if (prop != nullptr && prop->IsIdentifier()) { + tmpName = prop->AsIdentifier()->Name().Utf8(); + nameView = std::string_view(tmpName); + } else { + checker->LogError(diagnostic::OVERLOADED_FUNCS_MUST_BE_IN_SAME_SCOPE, {}, expr->Start()); + expr->SetTsType(checker->GlobalTypeError()); + return; + } + } else { + tmpName = expr->ToString(); + nameView = std::string_view(tmpName); + } + + auto *var = overloadScope->FindLocal(nameView, varbinder::ResolveBindingOptions::ALL); + if (var == nullptr) { + checker->LogError(diagnostic::OVERLOADED_FUNCS_MUST_BE_IN_SAME_SCOPE, {}, expr->Start()); + expr->SetTsType(checker->GlobalTypeError()); + return; + } + if (var->Declaration() && var->Declaration()->IsImportDecl()) { + checker->LogError(diagnostic::OVERLOADED_FUNCS_MUST_BE_IN_SAME_SCOPE, {}, expr->Start()); + expr->SetTsType(checker->GlobalTypeError()); + return; + } + } +} + checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const { ETSChecker *checker = GetETSChecker(); @@ -380,6 +426,7 @@ checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const CheckDuplicationInOverloadDeclaration(checker, node); CheckOverloadSameNameMethod(checker, node); + CheckOverloadFunctionInNamespace(checker, node); if (node->IsConstructorOverloadDeclaration()) { ES2PANDA_ASSERT(node->Parent()->IsClassDefinition()); diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_5.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_5.ets index c7a80816f02fbb0dec419f0ca02691fb0e1239bb..e448560ca1a97576dae1424e9684c72f537f0109 100644 --- a/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_5.ets +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_5.ets @@ -16,6 +16,7 @@ overload foo{ foo.,T,} /* @@? 16:19 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 16:19 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ /* @@? 16:19 Error TypeError: overloaded name must refer to an accessible method. */ /* @@? 16:20 Error SyntaxError: Unexpected token, expected ',' or '}'. */ /* @@? 16:20 Error TypeError: Unresolved reference T */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declare.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declare.ets index 090aa4c25a1bed2ae8e7fdd14100942d82869e32..ca081c78fa47373330d808f9f84c0ee8269ec8cb 100644 --- a/ets2panda/test/ast/compiler/ets/first_match/invalid_declare.ets +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declare.ets @@ -18,6 +18,11 @@ overload * you thMMMMMMMMdSTICKER, /* @@? 16:10 Error SyntaxError: Identifier expected, got '*'. */ /* @@? 16:12 Error SyntaxError: Unexpected token, expected '{'. */ /* @@? 16:12 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 16:12 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ +/* @@? 16:12 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 16:12 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ +/* @@? 16:12 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 16:12 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ /* @@? 16:12 Error TypeError: overloaded name must refer to an accessible method. */ /* @@? 16:16 Error SyntaxError: Unexpected token, expected ',' or '}'. */ /* @@? 16:16 Error TypeError: Unresolved reference thMMMMMMMMdSTICKER */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_identifier.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_identifier.ets index 597ad29e1a5d28de16e8d6f818b30dbc7bc1b145..3d7f50309e04ddaf3f9f30d8458f6c5aa8307866 100644 --- a/ets2panda/test/ast/compiler/ets/first_match/invalid_identifier.ets +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_identifier.ets @@ -42,6 +42,7 @@ function main(){ /* @@? 22:20 Error SyntaxError: Unexpected token, expected '{'. */ /* @@? 22:20 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 22:20 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 22:20 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ /* @@? 22:21 Error SyntaxError: Unexpected token, expected ',' or '}'. */ /* @@? 22:21 Error TypeError: Unresolved reference foo1 */ /* @@? 22:25 Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/function_overloaded_name_must_qualified_name.ets b/ets2panda/test/ast/compiler/ets/overload/function_overloaded_name_must_qualified_name.ets index 70eb87ba28801033a1a0e893285a0f3c51c5141e..8559cd1042fad6ef9be77bcc1aaf9b5d542a4878 100644 --- a/ets2panda/test/ast/compiler/ets/overload/function_overloaded_name_must_qualified_name.ets +++ b/ets2panda/test/ast/compiler/ets/overload/function_overloaded_name_must_qualified_name.ets @@ -21,6 +21,7 @@ namespace NS { } } -overload foo {NS.foo1, NS.A.foo2, /* @@ label1 */NS.A.foo2} +overload foo {NS.foo1, NS.A.foo2, NS.A.foo2} -/* @@@ label1 Error TypeError: Duplicate overloaded method. */ +/* @@? 24:15 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ +/* @@? 24:35 Error TypeError: Duplicate overloaded method. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function_2.ets b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function_2.ets index fa182d50daa9913808bdd440e4bedca29bc69dac..cd8e02b193cab5165ddc4a71fa653b5501ed8a08 100644 --- a/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function_2.ets +++ b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function_2.ets @@ -30,8 +30,7 @@ namespace NS { }; } +overload foo{ NS.NS2.foo1, NS.NS2.NS3.foo2, NS.foo3, NS.NS2.NS3.foo2}; -overload foo{ NS.NS2.foo1, NS.NS2.NS3.foo2, NS.foo3, /* @@ label1 */NS.NS2.NS3.foo2}; - -/* @@@ label1 Error TypeError: Duplicate overloaded method. */ - +/* @@? 33:15 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ +/* @@? 33:54 Error TypeError: Duplicate overloaded method. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module.ets b/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module.ets new file mode 100644 index 0000000000000000000000000000000000000000..ea8c8e86b9d6213f5c5fb1da8b45bc4a05dc0a70 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module.ets @@ -0,0 +1,34 @@ +/* + * 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 {foo1} from "./module" + +function foo2() {} +overload foo {foo1, foo2} // compile-time error + +namespace N { + export function fooN() {} + namespace M { + export function fooM() {} + } + overload goo {M.fooM, fooN} // compile-time error +} + +overload bar {foo2, N.fooN} // compile-time error + +/* @@? 19:15 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ +/* @@? 19:15 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 26:16 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ +/* @@? 29:21 Error TypeError: All overloaded functions must be declared in the same module or namespace scope. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_1.ets b/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..f74e6e838c493c71d0cffbec0def377ba4a55967 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_1.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ + + namespace N { + export function fooN() {} + export function fooM() {} + + overload goo {N.fooM, fooN} +} diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_2.ets b/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d393ac49f104558a3a69328cc323e8470555167 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_2.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. + */ + +namespace A { + export function fooN() {} +} + +namespace A { + export function fooM() {} + overload goo {A.fooM, A.fooN} +} diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_3.ets b/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..b2665c87f63e7f086c87442f645f57dfdaa0ef07 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_in_namespace_and_module_3.ets @@ -0,0 +1,26 @@ +/* + * 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. + */ + + +namespace A { + export namespace B { + export function fooM() {} + } +} + +namespace A.B { + export function fooN() {} + overload goo {A.B.fooM, A.B.fooN} +} diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 5b7a9bdbff9630242492a0859864346d39f0e79b..847af89b57a21bf61f71cf10ce7e17613107f099 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -1037,6 +1037,10 @@ semantic: id: 4101 message: "Arithmetic operation causes an overflow." +- name: OVERLOADED_FUNCS_MUST_BE_IN_SAME_SCOPE + id: 340 + message: "All overloaded functions must be declared in the same module or namespace scope." + - name: OVERLOADED_MAIN id: 373 message: "Main overload is not enabled" @@ -1527,7 +1531,6 @@ graveyard: - 325 - 328 - 339 -- 340 - 341 - 348 - 352