diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index e36ae97b91d21132b6e00a4ec2d7afd9ee9ccf41..b97fd7aed28f1faec6a85f3618f521220149f18a 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -238,6 +238,15 @@ void ScopesInitPhase::VisitVariableDeclarator(ir::VariableDeclarator *varDecl) auto init = varDecl->Id(); std::vector bindings = util::Helpers::CollectBindingNames(VarBinder(), init); for (auto *binding : bindings) { + auto name = binding->Name(); + if (binding->Variable() == nullptr && !name.Is(ERROR_LITERAL) && VarBinder()->IsETSBinder()) { + auto var = VarBinder()->GetScope()->FindLocal(name, varbinder::ResolveBindingOptions::ALL_VARIABLES); + if (var != nullptr) { + VarBinder()->ThrowRedeclaration(binding->Start(), name, var->Declaration()->Type()); + continue; + } + } + auto [decl, var] = AddOrGetVarDecl(varDecl->Flag(), binding); BindVarDecl(binding, init, decl, var); } @@ -498,7 +507,7 @@ std::tuple ScopesInitPhase::AddOrGetVa name = compiler::GenName(Allocator()).View(); } else if (VarBinder()->IsETSBinder()) { if (auto var = scope->FindLocal(name, varbinder::ResolveBindingOptions::ALL_VARIABLES); var != nullptr) { - VarBinder()->ThrowRedeclaration(id->Start(), name, var->Declaration()->Type()); + ES2PANDA_ASSERT(ctx_->diagnosticEngine->IsAnyError()); return {var->Declaration(), var}; } } diff --git a/ets2panda/test/ast/compiler/ets/class_without_closing_parentheses.ets b/ets2panda/test/ast/compiler/ets/class_without_closing_parentheses.ets index 4c4d1ca68c2f3f6c8f275eeda94077be514aa2bf..2926286b817fccaa6a16213dcdb5454341873c23 100644 --- a/ets2panda/test/ast/compiler/ets/class_without_closing_parentheses.ets +++ b/ets2panda/test/ast/compiler/ets/class_without_closing_parentheses.ets @@ -37,4 +37,4 @@ export default class TreeMap implements ReadonlyTreeMap { /* @@? 21:15 Error TypeError: Variable 'buffer' has already been declared. */ /* @@? 21:15 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 24:32 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 26:20 Error TypeError: Cannot find type 'buffer'. */ +/* @@? 26:20 Error TypeError: Namespace 'buffer' cannot be used as a type. */ diff --git a/ets2panda/test/ast/compiler/ets/redecl_func_arow_param_in_body.ets b/ets2panda/test/ast/compiler/ets/redecl_func_arow_param_in_body.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0f98280f500bc543bcfad24cadfd07042e1dc8b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/redecl_func_arow_param_in_body.ets @@ -0,0 +1,31 @@ +/* + * 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 ermissions and + * limitatioLicense. + * 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. + */ + +function foo(bar: () => int) { + let x , bar(); + } + + function main(): void { + foo(() => {}); + } + +/* @@? 18:11 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 18:13 Error TypeError: Variable 'bar' has already been declared. */ +/* @@? 18:16 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 18:16 Error SyntaxError: Unexpected token '('. */ +/* @@? 18:17 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:18 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 22:14 Error TypeError: Type 'void' is not compatible with the enclosing method's return type 'Int' */