diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index aa6eb3ff15eeeb4e0fd60cd6b0bac4846ce45784..10d0b983d65b1d7eafe89135f9821d49b47436ff 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1073,6 +1073,33 @@ checker::Type *ETSAnalyzer::GetSmartType(ir::AssignmentExpression *expr, checker return smartType; } +static bool IsMethodDefinition(const ir::Expression *const expression) +{ + return expression->IsMemberExpression() && expression->AsMemberExpression()->Property() != nullptr && + expression->AsMemberExpression()->Property()->Variable() != nullptr && + expression->AsMemberExpression()->Property()->Variable()->Declaration() != nullptr && + expression->AsMemberExpression()->Property()->Variable()->Declaration()->Node()->IsMethodDefinition(); +} + +static bool IsInvalidMethodAssignment(const ir::AssignmentExpression *const expr, ETSChecker *checker) +{ + auto left = expr->Left(); + if (IsMethodDefinition(left)) { + { + auto methodDefinition = + left->AsMemberExpression()->Property()->Variable()->Declaration()->Node()->AsMethodDefinition(); + if (!methodDefinition->IsSetter() && + std::none_of(methodDefinition->Overloads().cbegin(), methodDefinition->Overloads().cend(), + [](const auto *overload) { return overload->IsSetter(); })) { + checker->LogError(diagnostic::METHOD_ASSIGNMENT, expr->Left()->Start()); + return true; + } + } + } + + return false; +} + checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const { if (expr->TsType() != nullptr) { @@ -1087,7 +1114,7 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const const auto leftType = expr->Left()->Check(checker); - if (IsInvalidArrayMemberAssignment(expr, checker)) { + if (IsInvalidArrayMemberAssignment(expr, checker) || IsInvalidMethodAssignment(expr, checker)) { expr->SetTsType(checker->GlobalTypeError()); return expr->TsType(); } diff --git a/ets2panda/test/ast/compiler/ets/identifierReference9.ets b/ets2panda/test/ast/compiler/ets/identifierReference9.ets index 006fc0197dbf87ac079541132e0dd7e22a2993ed..3021ebf7a1953f57ccd1e53d8ba2ba11c4805025 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference9.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference9.ets @@ -25,4 +25,4 @@ class A { } } -/* @@? 24:16 Error TypeError: Type 'Int' cannot be assigned to type '() => void' */ +/* @@? 24:5 Error TypeError: Class methods cannot be overwritten. */ diff --git a/ets2panda/test/ast/compiler/ets/method-assignment.ets b/ets2panda/test/ast/compiler/ets/method-assignment.ets new file mode 100644 index 0000000000000000000000000000000000000000..8bf46b3b8dda5d946381769cc48228a96d5c63f8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/method-assignment.ets @@ -0,0 +1,56 @@ +/* + * 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. + */ + +class Base { + baseFoo() {} + static staticBaseFoo() {} +} + +interface I { + interfaceFoo() {} +} + +class C extends Base implements I { + foo1() {} + static foo2() {} + + constructor() + { + this.interfaceFoo = bar; + } + + constructor(arg: () => void) + { + this.foo1 = arg; + } +} + +function bar() {} + +let c = new C(); +c = new C(bar); +c.baseFoo = bar; +C.staticBaseFoo = bar; +c.foo1 = bar; +C.foo2 = bar; +c.interfaceFoo = bar; + +/* @@? 31:9 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 36:9 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 44:1 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 45:1 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 46:1 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 47:1 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 48:1 Error TypeError: Class methods cannot be overwritten. */ diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 4c4ae2e28ecd4f21ea96d41b0697c01a66857615..98f294186329dc3ac0f3d53b6401673de29d1f10 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -1514,3 +1514,7 @@ semantic: - name: DYMANIC_INIT_WITH_OBJEXPR id: 382 message: "Dymanic Type {} cannot be initialize with an object expression" + +- name: METHOD_ASSIGNMENT + id: 383 + message: "Class methods cannot be overwritten." \ No newline at end of file