diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 6b6789ee59f387bea4531d97a06224cd94b3175e..4f1cb7d0c39453ea138013f489568309c9d737ad 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -65,11 +65,15 @@ checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const { ETSChecker *checker = GetETSChecker(); + if (node->TsType() == nullptr) { checker->BuildBasicClassProperties(node); } - checker->CheckClassDefinition(node); + if (!node->IsClassDefinitionChecked()) { + checker->CheckClassDefinition(node); + } + return nullptr; } @@ -1083,6 +1087,10 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const if (expr->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) { checker::SavedCheckerContext savedCtx(checker, checker->Context().Status(), expr->Signature()->Owner()); expr->Signature()->OwnerVar()->Declaration()->Node()->Check(checker); + if (expr->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE) && + expr->Signature()->Function()->HasBody()) { + checker->CollectReturnStatements(expr->Signature()->Function()); + } returnType = expr->Signature()->ReturnType(); // NOTE(vpukhov): #14902 substituted signature is not updated } @@ -2478,14 +2486,16 @@ checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const checker::ETSObjectType *interfaceType {}; - if (st->TsType() == nullptr) { - interfaceType = checker->BuildBasicInterfaceProperties(st); - ASSERT(interfaceType != nullptr); - interfaceType->SetSuperType(checker->GlobalETSObjectType()); - checker->CheckInvokeMethodsLegitimacy(interfaceType); - st->SetTsType(interfaceType); + if (st->TsType() != nullptr) { + return st->TsType(); } + interfaceType = checker->BuildBasicInterfaceProperties(st); + ASSERT(interfaceType != nullptr); + interfaceType->SetSuperType(checker->GlobalETSObjectType()); + checker->CheckInvokeMethodsLegitimacy(interfaceType); + st->SetTsType(interfaceType); + checker::ScopeContext scopeCtx(checker, st->Scope()); auto savedContext = checker::SavedCheckerContext(checker, checker::CheckerStatus::IN_INTERFACE, interfaceType); diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index d892ccf2eeccb984992e6d65df24d54e99426595..040e6dffa4592f1d71ddb0471e868539525d491f 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -85,6 +85,10 @@ void CheckExtensionMethod(checker::ETSChecker *checker, ir::ScriptFunction *exte !classType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::INTERFACE))) { checker->ThrowTypeError("Extension function can only defined for class and interface type.", node->Start()); } + if (classType->Variable()->Declaration()->Node()->IsClassDefinition() && + !classType->Variable()->Declaration()->Node()->AsClassDefinition()->IsClassDefinitionChecked()) { + classType->Variable()->Declaration()->Node()->Check(checker); + } // NOTE(gogabr): should be done in a lowering ReplaceThisInExtensionMethod(checker, extensionFunc); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 46185b17fd161ea3e063e209f1878321074f142f..f994fce0eafef8df93fa47626c41874c6ea4da57 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -633,6 +633,7 @@ public: ETSObjectType *GetCachedFunctionalInterface(ir::ETSFunctionType *type); void CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectType *ifaceType); + void CollectReturnStatements(ir::AstNode *parent); ir::ETSParameterExpression *AddParam(util::StringView name, ir::TypeNode *type); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 75930ae11b83fcad08e636c58eda2149e0e1f1a3..a28587c49dc3f6c951c84f78af25e86087e59345 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1876,4 +1876,20 @@ void ETSChecker::CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectTy functionalInterfaceCache_.emplace(hash, ifaceType); } +void ETSChecker::CollectReturnStatements(ir::AstNode *parent) +{ + parent->Iterate([this](ir::AstNode *childNode) -> void { + if (childNode->IsScriptFunction()) { + return; + } + + if (childNode->IsReturnStatement()) { + ir::ReturnStatement *returnStmt = childNode->AsReturnStatement(); + returnStmt->Check(this); + } + + CollectReturnStatements(childNode); + }); +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index a68f0cab736462106932d157a7b2a0bc9e3b9a82..c9483d4d89810c942785be8922ebddf16199ef91 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2160,6 +2160,9 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A memberExpression->SetTsType(field->TsType()); memberExpression->SetPropVar(field->Key()->Variable()->AsLocalVariable()); memberExpression->SetRange(classDef->Range()); + if (memberExpression->ObjType() == nullptr && classDef->TsType() != nullptr) { + memberExpression->SetObjectType(classDef->TsType()->AsETSObjectType()); + } if (!isSetter) { stmts.push_back(AllocNode(memberExpression)); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index aeb7272c09aef4812746dfe6cef7f9a84f40e447..575de767d280727da37ea44923144b13b2fad007 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -714,6 +714,10 @@ void ETSChecker::ValidateOverriding(ETSObjectType *classType, const lexer::Sourc isSetter = (*abstractSignature)->HasSignatureFlag(SignatureFlags::SETTER); isExternal = (*abstractSignature)->Function()->IsExternal(); for (auto *const implemented : implementedSignatures) { + if (implemented->HasSignatureFlag(SignatureFlags::NEED_RETURN_TYPE)) { + implemented->OwnerVar()->Declaration()->Node()->Check(this); + } + Signature *substImplemented = AdjustForTypeParameters(*abstractSignature, implemented); if (substImplemented == nullptr) { @@ -862,6 +866,10 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) { classDef->SetClassDefinitionChecked(); auto *classType = classDef->TsType()->AsETSObjectType(); + if (classType->SuperType() != nullptr) { + classType->SuperType()->GetDeclNode()->Check(this); + } + auto newStatus = checker::CheckerStatus::IN_CLASS; classType->SetEnclosingType(Context().ContainingClass()); diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 33c021fe042e7dcaf177bb3b8c187ea745bc1b36..ec9c3ed180ff7a0c6120a7de1dead4e791b2e3c5 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -911,7 +911,7 @@ void ETSObjectType::InstantiateProperties() const } ASSERT(!propertiesInstantiated_); - checker->ResolveDeclaredMembersOfObject(this); + declNode_->Check(checker); for (auto *const it : baseType_->ConstructSignatures()) { auto *newSig = it->Substitute(relation_, substitution_); diff --git a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type-expected.txt b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..9df2f1fefb3b1008de796eeccf266bf5ca9e5f1f --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type-expected.txt @@ -0,0 +1,478 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./infer_imported_function_return_type_lib", + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 62 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "imported": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 63 + } + } + }, + { + "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 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 20 + } + } + }, + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 19, + "column": 21 + }, + "end": { + "line": 19, + "column": 24 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 10 + } + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 27 + }, + "end": { + "line": 19, + "column": 30 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 19, + "column": 31 + }, + "end": { + "line": 19, + "column": 32 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 19, + "column": 27 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 33 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 34 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "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": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type.ets b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe40b45e9559014ff7169965c36d4f478f302521 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type.ets @@ -0,0 +1,20 @@ +/* + * 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. + */ + +import {foo} from "./infer_imported_function_return_type_lib"; + +function main() { + let x: String | int = foo(1); +} diff --git a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..ef9faebfed894463fcce88ad4ffef9f6cc5fc5cf --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt @@ -0,0 +1,458 @@ +{ + "type": "Program", + "statements": [ + { + "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 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "param", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 28 + }, + "end": { + "line": 16, + "column": 31 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 31 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "operator": "==", + "left": { + "type": "BinaryExpression", + "operator": "%", + "left": { + "type": "Identifier", + "name": "param", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "alternate": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "StringLiteral", + "value": "x", + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 20, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 33 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 20 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 20 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "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": 23, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib.ets b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib.ets new file mode 100644 index 0000000000000000000000000000000000000000..cc8f36b06491c3d59a7029200f200e6e6722a2d2 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +export function foo(param: int) { + if (param % 2 == 0) + { return 1; + } else { + return "x";} +} + diff --git a/ets2panda/test/parser/ets/infer_overriding_method_return_type-expected.txt b/ets2panda/test/parser/ets/infer_overriding_method_return_type-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..0a41ac4d4d4c90867d36ea8caaf758d3d6aaf8a8 --- /dev/null +++ b/ets2panda/test/parser/ets/infer_overriding_method_return_type-expected.txt @@ -0,0 +1,710 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Base", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "method", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "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": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + { + "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": 21 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Derived", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Base", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 23 + }, + "end": { + "line": 20, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 23 + }, + "end": { + "line": 20, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 23 + }, + "end": { + "line": 20, + "column": 29 + } + } + }, + "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": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 22, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 23, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 23, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 23, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 23, + "column": 6 + } + } + }, + { + "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": 24, + "column": 2 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 28 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + { + "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": 24, + "column": 2 + } + } +} diff --git a/ets2panda/test/parser/ets/infer_overriding_method_return_type.ets b/ets2panda/test/parser/ets/infer_overriding_method_return_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..be2de8df6de0482b842eee8f4f7e16cf976573c5 --- /dev/null +++ b/ets2panda/test/parser/ets/infer_overriding_method_return_type.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +abstract class Base { + abstract method(): number; +} + +class Derived extends Base { + method() { + return 1.0 + }; +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/infer_method_type_1.ets b/ets2panda/test/runtime/ets/infer_method_type_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..b4e953f69b437eb246d6ad0330e5627d46c6d725 --- /dev/null +++ b/ets2panda/test/runtime/ets/infer_method_type_1.ets @@ -0,0 +1,44 @@ +/* + * 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 Pot { + private v: T + constructor(v: T) { + this.v = v + } + set(v: T) { + this.v = v; + return this; + } + get(): T { + return this.v; + } +} + +function main() { +let p = new Pot("") +let q = new Pot(0) + +p.set("a") +assert p.get() == "a" +q.set(1) +assert q.get() == 1 +p.set("b").set("c") +assert p.get() == "c" +p = p.set("d") +assert p.get() == "d" +q = q.set(2) +assert q.get() == 2 +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/infer_method_type_2.ets b/ets2panda/test/runtime/ets/infer_method_type_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..446c463917473d743a0a4c40bb724664543575d3 --- /dev/null +++ b/ets2panda/test/runtime/ets/infer_method_type_2.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +abstract class Base { + abstract method(): number; +} + +class Derived extends Base { + method() { + return 1.0 + }; +} + +function main() { + assert 1 == new Derived().method() +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/infer_method_type_3.ets b/ets2panda/test/runtime/ets/infer_method_type_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..6acfb8b68b6a3ae2044f87d7692499f730cde294 --- /dev/null +++ b/ets2panda/test/runtime/ets/infer_method_type_3.ets @@ -0,0 +1,30 @@ +/* + * 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 A { + a = 1 +} + +class Base { + get foo() { + return new A(); + } +} + +class Derived extends Base { +} + +let y: A = new Derived().foo; +assert y.a == 1 diff --git a/ets2panda/test/runtime/ets/infer_method_type_4.ets b/ets2panda/test/runtime/ets/infer_method_type_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..73eab25ee82c59a171e34212ebe95fb826690cc6 --- /dev/null +++ b/ets2panda/test/runtime/ets/infer_method_type_4.ets @@ -0,0 +1,41 @@ +/* + * 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 A { + a: int + constructor(param: int) { + this.a = param + } +} + +class Base { + get foo() { + return new A(1); + } +} + +class Derived extends Base { + get foo() { + return new A(2); + } +} + +let x: Derived = new Derived(); +let y = x.foo; +assert y.a == 2; + +let v: Base = new Base(); +let w = v.foo; +assert w.a == 1;