diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index e909286f9379778b42a2def9136e029356ee7fb0..6d6cb8403f7a0fc2b3121f350074dedacac700b7 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -362,7 +362,6 @@ public: bool IsOverridableIn(Signature *signature); [[nodiscard]] bool AreOverrideEquivalent(Signature *s1, Signature *s2); [[nodiscard]] bool IsReturnTypeSubstitutable(Signature *s1, Signature *s2); - void CheckStaticHide(Signature *target, Signature *source); void CheckThrowMarkers(Signature *source, Signature *target); void ValidateSignatureAccessibility(ETSObjectType *callee, const ir::CallExpression *callExpr, Signature *signature, const lexer::SourcePosition &pos, char const *errorMessage = nullptr); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index e6476c47e5aa9b87ce662392da988ef5231198fc..e2e8aeed4be14b0e705e27bff117e803d2f26a7d 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1090,6 +1090,10 @@ bool ETSChecker::IsMethodOverridesOther(Signature *target, Signature *source) return true; } + if (source->HasSignatureFlag(SignatureFlags::STATIC) != target->HasSignatureFlag(SignatureFlags::STATIC)) { + return false; + } + if (IsOverridableIn(target)) { SavedTypeRelationFlagsContext savedFlagsCtx(Relation(), TypeRelationFlag::NO_RETURN_TYPE_CHECK); Relation()->IsIdenticalTo(target, source); @@ -1108,19 +1112,6 @@ bool ETSChecker::IsMethodOverridesOther(Signature *target, Signature *source) return false; } -void ETSChecker::CheckStaticHide(Signature *target, Signature *source) -{ - if (!target->HasSignatureFlag(SignatureFlags::STATIC) && source->HasSignatureFlag(SignatureFlags::STATIC)) { - ThrowTypeError("A static method hides an instance method.", source->Function()->Body()->Start()); - } - - if ((target->HasSignatureFlag(SignatureFlags::STATIC) || - (source->HasSignatureFlag(SignatureFlags::STATIC) || !source->Function()->IsOverride())) && - !IsReturnTypeSubstitutable(target, source)) { - ThrowTypeError("Hiding method is not return-type-substitutable for other method.", source->Function()->Start()); - } -} - void ETSChecker::CheckThrowMarkers(Signature *source, Signature *target) { ir::ScriptFunctionFlags throwMarkers = ir::ScriptFunctionFlags::THROWS | ir::ScriptFunctionFlags::RETHROWS; @@ -1139,10 +1130,6 @@ void ETSChecker::CheckThrowMarkers(Signature *source, Signature *target) std::tuple ETSChecker::CheckOverride(Signature *signature, Signature *other) { if (other->HasSignatureFlag(SignatureFlags::STATIC)) { - if (signature->Function()->IsOverride()) { - return {false, OverrideErrorCode::OVERRIDDEN_STATIC}; - } - ASSERT(signature->HasSignatureFlag(SignatureFlags::STATIC)); return {true, OverrideErrorCode::NO_ERROR}; } @@ -1187,10 +1174,6 @@ void ETSChecker::ThrowOverrideError(Signature *signature, Signature *overriddenS { const char *reason {}; switch (errorCode) { - case OverrideErrorCode::OVERRIDDEN_STATIC: { - reason = "overridden method is static."; - break; - } case OverrideErrorCode::OVERRIDDEN_FINAL: { reason = "overridden method is final."; break; @@ -1226,13 +1209,6 @@ bool ETSChecker::CheckOverride(Signature *signature, ETSObjectType *site) for (auto *it : target->TsType()->AsETSFunctionType()->CallSignatures()) { auto *itSubst = AdjustForTypeParameters(signature, it); - if (signature->Owner()->HasObjectFlag(ETSObjectFlags::INTERFACE) && - Relation()->IsIdenticalTo(itSubst->Owner(), GlobalETSObjectType()) && - !itSubst->HasSignatureFlag(SignatureFlags::PRIVATE)) { - ThrowTypeError("Cannot override non-private method of the class Object from an interface.", - signature->Function()->Start()); - } - if (itSubst == nullptr) { continue; } @@ -1256,6 +1232,13 @@ bool ETSChecker::CheckOverride(Signature *signature, ETSObjectType *site) ThrowOverrideError(signature, it, errorCode); } + if (signature->Owner()->HasObjectFlag(ETSObjectFlags::INTERFACE) && + Relation()->IsIdenticalTo(itSubst->Owner(), GlobalETSObjectType()) && + !itSubst->HasSignatureFlag(SignatureFlags::PRIVATE)) { + ThrowTypeError("Cannot override non-private method of the class Object from an interface.", + signature->Function()->Start()); + } + isOverridingAnySignature = true; it->AddSignatureFlag(SignatureFlags::VIRTUAL); } diff --git a/ets2panda/checker/resolveResult.h b/ets2panda/checker/resolveResult.h index 8d9470c5fdcbf88bc39d3807d2331b56188b497b..2391c21207ece59c68a354f9d49472896b8fd56c 100644 --- a/ets2panda/checker/resolveResult.h +++ b/ets2panda/checker/resolveResult.h @@ -19,8 +19,6 @@ namespace panda::es2panda::checker { enum class OverrideErrorCode { NO_ERROR, - OVERRIDING_STATIC, - OVERRIDDEN_STATIC, OVERRIDDEN_FINAL, INCOMPATIBLE_RETURN, OVERRIDDEN_WEAKER, diff --git a/ets2panda/test/parser/ets/overrideStaticFunc-expected.txt b/ets2panda/test/parser/ets/overrideStaticFunc-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..65967293ae8a9d0d0322c906a6341e811ab0c0a6 --- /dev/null +++ b/ets2panda/test/parser/ets/overrideStaticFunc-expected.txt @@ -0,0 +1,917 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "method", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "method", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 28 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 2 + }, + "end": { + "line": 18, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 11 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 24 + } + } + }, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "method", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 11 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "method", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 11 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 21, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 21, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 21, + "column": 21 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 21, + "column": 20 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 2 + }, + "end": { + "line": 22, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 23 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "keys", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 9 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "keys", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 9 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 19 + } + } + }, + "declare": true, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 25, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 9 + }, + "end": { + "line": 25, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 9 + }, + "end": { + "line": 25, + "column": 20 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 20 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 17 + }, + "end": { + "line": 26, + "column": 2 + } + } + }, + "id": { + "type": "Identifier", + "name": "inter", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 11 + }, + "end": { + "line": 24, + "column": 16 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 24, + "column": 1 + }, + "end": { + "line": 27, + "column": 1 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 27, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/overrideStaticFunc.ets b/ets2panda/test/parser/ets/overrideStaticFunc.ets new file mode 100644 index 0000000000000000000000000000000000000000..4bdc0030bbf597ce0c3057535037ed3779642f9c --- /dev/null +++ b/ets2panda/test/parser/ets/overrideStaticFunc.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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 foo { + static method(): void {} +} + +class bar extends foo { + method(): void {} +} + +interface inter { + keys(): void {} +} diff --git a/ets2panda/test/parser/ets/static_function_hide_1-expected.txt b/ets2panda/test/parser/ets/static_function_override_1-expected.txt similarity index 100% rename from ets2panda/test/parser/ets/static_function_hide_1-expected.txt rename to ets2panda/test/parser/ets/static_function_override_1-expected.txt diff --git a/ets2panda/test/parser/ets/static_function_hide_1.ets b/ets2panda/test/parser/ets/static_function_override_1.ets similarity index 100% rename from ets2panda/test/parser/ets/static_function_hide_1.ets rename to ets2panda/test/parser/ets/static_function_override_1.ets diff --git a/ets2panda/test/parser/ets/static_function_hide_2-expected.txt b/ets2panda/test/parser/ets/static_function_override_2-expected.txt similarity index 99% rename from ets2panda/test/parser/ets/static_function_hide_2-expected.txt rename to ets2panda/test/parser/ets/static_function_override_2-expected.txt index f025fefb85e34ca329255e1e5c3da8f2782cc6ab..5a8bd4498570c14ff5a7ae4b888ea62f0550c19b 100644 --- a/ets2panda/test/parser/ets/static_function_hide_2-expected.txt +++ b/ets2panda/test/parser/ets/static_function_override_2-expected.txt @@ -735,4 +735,3 @@ } } } -TypeError: A static method hides an instance method. [static_function_hide_2.ets:21:24] diff --git a/ets2panda/test/parser/ets/static_function_hide_2.ets b/ets2panda/test/parser/ets/static_function_override_2.ets similarity index 100% rename from ets2panda/test/parser/ets/static_function_hide_2.ets rename to ets2panda/test/parser/ets/static_function_override_2.ets diff --git a/ets2panda/test/parser/ets/static_function_hide_3-expected.txt b/ets2panda/test/parser/ets/static_function_override_3-expected.txt similarity index 99% rename from ets2panda/test/parser/ets/static_function_hide_3-expected.txt rename to ets2panda/test/parser/ets/static_function_override_3-expected.txt index 6cb06f2cb9eb27800444766f4879f5fdf2cefc93..ef25ad70850606acffa7a6a3ff434fc741769e43 100644 --- a/ets2panda/test/parser/ets/static_function_hide_3-expected.txt +++ b/ets2panda/test/parser/ets/static_function_override_3-expected.txt @@ -735,4 +735,3 @@ } } } -TypeError: bar(): void in BClass cannot override bar(): void in AClass because overridden method is static. [static_function_hide_3.ets:21:8] diff --git a/ets2panda/test/parser/ets/static_function_hide_3.ets b/ets2panda/test/parser/ets/static_function_override_3.ets similarity index 100% rename from ets2panda/test/parser/ets/static_function_hide_3.ets rename to ets2panda/test/parser/ets/static_function_override_3.ets diff --git a/ets2panda/test/parser/ets/static_function_hide_4-expected.txt b/ets2panda/test/parser/ets/static_function_override_4-expected.txt similarity index 99% rename from ets2panda/test/parser/ets/static_function_hide_4-expected.txt rename to ets2panda/test/parser/ets/static_function_override_4-expected.txt index 9ce1e68329c377feb7f07c6421d16a04d41a0341..5d48d160d58fc5f4cbe1ee24eb32e050cac2be1e 100644 --- a/ets2panda/test/parser/ets/static_function_hide_4-expected.txt +++ b/ets2panda/test/parser/ets/static_function_override_4-expected.txt @@ -735,4 +735,4 @@ } } } -TypeError: bar(): void in BClass cannot override bar(): void in AClass because overridden method is static. [static_function_hide_4.ets:21:17] +TypeError: Method bar(): void in BClass not overriding any method [static_function_override_4.ets:21:17] diff --git a/ets2panda/test/parser/ets/static_function_hide_4.ets b/ets2panda/test/parser/ets/static_function_override_4.ets similarity index 100% rename from ets2panda/test/parser/ets/static_function_hide_4.ets rename to ets2panda/test/parser/ets/static_function_override_4.ets diff --git a/ets2panda/test/test-lists/parser/parser-js-ignored.txt b/ets2panda/test/test-lists/parser/parser-js-ignored.txt index a0cac35d0e8d349ebf833c8793d6cfe4aae7a44a..d63cc2086bf1cdb365dac48db82c8c832e0243c6 100644 --- a/ets2panda/test/test-lists/parser/parser-js-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-js-ignored.txt @@ -74,7 +74,6 @@ compiler/ets/override13.ets compiler/ets/methodOverrideCovariantReturnType.ets compiler/ets/override16.ets compiler/ets/override17.ets -parser/ets/static_function_hide_2.ets # 14595 compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets