From c557100ba29b3fb5d824164effd3773bbc8e5647 Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Sat, 17 Aug 2024 17:19:14 +0800 Subject: [PATCH] Fix assertion failure when initializing function type array Issue:#IAE460:[Bug]: Assertion error when initializing function type array Reason:When creating an array of function types, ETSFunctionType::ToAssemblerType is called, but this function is "UNREACHABLE", causing an assertion failure. Description:Added a new member variable funcinterface to ETSFunctionType, and implemented etsFucntionType::ToAssemblerType. In order to compute funcInterface only once, split the BuildFunctionSignature function, and adjusted the order of Check(ir::ArrowFunctionExpression *expr), check the body first and then create ETSFunctionType. Tests: ninja tests passed bash ets_testrunner.sh --cts -r -rt passed Signed-off-by: xuxinjie4 --- ets2panda/checker/ETSAnalyzer.cpp | 46 +- ets2panda/checker/ETSchecker.h | 6 +- ets2panda/checker/ets/function.cpp | 26 +- ets2panda/checker/ets/helpers.cpp | 18 +- ets2panda/checker/ets/typeCreation.cpp | 25 + .../types/ets/etsDynamicFunctionType.h | 10 +- .../checker/types/ets/etsFunctionType.cpp | 8 + ets2panda/checker/types/ets/etsFunctionType.h | 15 +- .../FunctionalTypeAsArrayElement-expected.txt | 528 ++++++++++++++++++ .../ets/FunctionalTypeAsArrayElement.sts | 21 + .../ets/FunctionalTypeAsArrayElement.sts | 24 + 11 files changed, 671 insertions(+), 56 deletions(-) create mode 100644 ets2panda/test/parser/ets/FunctionalTypeAsArrayElement-expected.txt create mode 100644 ets2panda/test/parser/ets/FunctionalTypeAsArrayElement.sts create mode 100644 ets2panda/test/runtime/ets/FunctionalTypeAsArrayElement.sts diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 9c89b40bc1..5f8955bbfd 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -15,6 +15,7 @@ #include "ETSAnalyzer.h" +#include "types/signature.h" #include "util/helpers.h" #include "checker/ETSchecker.h" #include "checker/ets/castingContext.h" @@ -99,7 +100,8 @@ checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const } auto *func = st->Function(); - st->SetTsType(checker->BuildFunctionSignature(func)); + checker->BuildFunctionSignature(func); + st->SetTsType(checker->BuildNamedFunctionType(func)); checker::ScopeContext scopeCtx(checker, func->Scope()); checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), checker->Context().ContainingClass()); @@ -641,25 +643,6 @@ checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const return expr->TsTypeOrError(); } - auto *funcType = checker->BuildFunctionSignature(expr->Function(), false); - - auto sigInfos = checker->ComposeSignatureInfosForArrowFunction(expr); - - for (auto &sigInfo : sigInfos) { - auto sig = checker->ComposeSignature(expr->Function(), sigInfo, - funcType->CallSignatures().front()->ReturnType(), nullptr); - sig->AddSignatureFlag(funcType->CallSignatures().front()->GetFlags()); - funcType->AddCallSignature(sig); - } - - if (expr->Function()->IsAsyncFunc()) { - auto *retType = expr->Function()->Signature()->ReturnType(); - if (!retType->IsETSObjectType() || - retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) { - checker->ThrowTypeError("Return type of async lambda must be 'Promise'", expr->Function()->Start()); - } - } - checker::ScopeContext scopeCtx(checker, expr->Function()->Scope()); if (checker->HasStatus(checker::CheckerStatus::IN_INSTANCE_EXTENSION_METHOD)) { @@ -683,14 +666,35 @@ checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), checker->Context().ContainingClass()); + checker->AddStatus(checker::CheckerStatus::IN_LAMBDA); - checker->Context().SetContainingSignature(funcType->CallSignatures()[0]); checker->Context().SetContainingLambda(expr); + checker->BuildFunctionSignature(expr->Function(), false); + auto *signature = expr->Function()->Signature(); + + checker->Context().SetContainingSignature(signature); expr->Function()->Body()->Check(checker); + ArenaVector signatures(checker->Allocator()->Adapter()); + signatures.push_back(signature); + for (auto &sigInfo : checker->ComposeSignatureInfosForArrowFunction(expr)) { + auto sig = checker->ComposeSignature(expr->Function(), sigInfo, signature->ReturnType(), nullptr); + sig->AddSignatureFlag(signature->GetFlags()); + signatures.push_back(sig); + } + + auto *funcType = checker->CreateETSFunctionType(expr->Function(), std::move(signatures), nullptr); checker->Context().SetContainingSignature(nullptr); + if (expr->Function()->IsAsyncFunc()) { + auto *retType = signature->ReturnType(); + if (!retType->IsETSObjectType() || + retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) { + checker->ThrowTypeError("Return type of async lambda must be 'Promise'", expr->Function()->Start()); + } + } + expr->SetTsType(funcType); return expr->TsType(); } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 7770f6f79a..fec4a4b7f7 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -261,9 +261,12 @@ public: ETSFunctionType *CreateETSFunctionType(ir::ScriptFunction *func, Signature *signature, util::StringView name); ETSFunctionType *CreateETSFunctionType(util::StringView name); ETSFunctionType *CreateETSFunctionType(ArenaVector &signatures); + ETSFunctionType *CreateETSFunctionType(ir::ScriptFunction *func, ArenaVector &&signature, + util::StringView name); ETSExtensionFuncHelperType *CreateETSExtensionFuncHelperType(ETSFunctionType *classMethodType, ETSFunctionType *extensionFunctionType); ETSObjectType *FunctionTypeToFunctionalInterfaceType(Signature *signature); + Type *ResolveFunctionalInterfaces(ArenaVector &signatures); ETSTypeParameter *CreateTypeParameter(); ETSObjectType *CreateETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags); std::tuple CreateBuiltinArraySignatureInfo(ETSArrayType *arrayType, size_t dim); @@ -424,7 +427,8 @@ public: ArenaVector ComposeSignatureInfosForArrowFunction(ir::ArrowFunctionExpression *arrowFuncExpr); void SetParamForSignatureInfoOfArrowFunction(SignatureInfo *signatureInfo, ir::ETSParameterExpression *param); void ValidateMainSignature(ir::ScriptFunction *func); - checker::ETSFunctionType *BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig = false); + void BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig = false); + checker::ETSFunctionType *BuildNamedFunctionType(ir::ScriptFunction *func); checker::ETSFunctionType *BuildMethodSignature(ir::MethodDefinition *method); Signature *CheckEveryAbstractSignatureIsOverridden(ETSFunctionType *target, ETSFunctionType *source); static Signature *GetSignatureFromMethodDefinition(const ir::MethodDefinition *methodDef); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 3a36e3ca09..49abb894dd 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -994,11 +994,12 @@ checker::ETSFunctionType *ETSChecker::BuildMethodSignature(ir::MethodDefinition bool isConstructSig = method->IsConstructor(); - auto *funcType = BuildFunctionSignature(method->Function(), isConstructSig); - + BuildFunctionSignature(method->Function(), isConstructSig); + auto *funcType = BuildNamedFunctionType(method->Function()); std::vector overloads; for (ir::MethodDefinition *const currentFunc : method->Overloads()) { - auto *const overloadType = BuildFunctionSignature(currentFunc->Function(), isConstructSig); + BuildFunctionSignature(currentFunc->Function(), isConstructSig); + auto *const overloadType = BuildNamedFunctionType(currentFunc->Function()); CheckIdenticalOverloads(funcType, overloadType, currentFunc); currentFunc->SetTsType(overloadType); funcType->AddCallSignature(currentFunc->Function()->Signature()); @@ -1297,7 +1298,7 @@ static void AddSignatureFlags(const ir::ScriptFunction *const func, Signature *c } } -checker::ETSFunctionType *ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig) +void ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig) { bool isArrow = func->IsArrow(); auto *nameVar = isArrow ? nullptr : func->Id()->Variable(); @@ -1320,18 +1321,17 @@ checker::ETSFunctionType *ETSChecker::BuildFunctionSignature(ir::ScriptFunction } else { signature->AddSignatureFlag(SignatureFlags::CALL); } - - auto *funcType = CreateETSFunctionType(func, signature, funcName); func->SetSignature(signature); - funcType->SetVariable(nameVar); - VarBinder()->AsETSBinder()->BuildFunctionName(func); - AddSignatureFlags(func, signature); + VarBinder()->AsETSBinder()->BuildFunctionName(func); +} - if (!isArrow) { - nameVar->SetTsType(funcType); - } - +checker::ETSFunctionType *ETSChecker::BuildNamedFunctionType(ir::ScriptFunction *func) +{ + ASSERT(!func->IsArrow()); + auto *nameVar = func->Id()->Variable(); + auto *funcType = CreateETSFunctionType(func, func->Signature(), nameVar->Name()); + funcType->SetVariable(nameVar); return funcType; } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index a57da8d779..cf92745fd4 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -694,26 +694,12 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T ThrowTypeError("Cannot get the expression type", init->Start()); } - bool isUnionFunction = false; - if (typeAnnotation == nullptr && initType->IsETSFunctionType()) { - if (initType->AsETSFunctionType()->CallSignatures().size() == 1) { - annotationType = - FunctionTypeToFunctionalInterfaceType(initType->AsETSFunctionType()->CallSignatures().front()); - } else { - ArenaVector types(Allocator()->Adapter()); - - for (auto &signature : initType->AsETSFunctionType()->CallSignatures()) { - types.push_back(FunctionTypeToFunctionalInterfaceType(signature)); - } - - annotationType = CreateETSUnionType(std::move(types)); - isUnionFunction = true; - } + annotationType = initType->AsETSFunctionType()->FunctionalInterface(); bindingVar->SetTsType(annotationType); } if (annotationType != nullptr) { - CheckAnnotationTypeForVariableDeclaration(annotationType, isUnionFunction, init, initType); + CheckAnnotationTypeForVariableDeclaration(annotationType, annotationType->IsETSUnionType(), init, initType); // Note(lujiahui): It should be checked if the readonly function parameter and readonly number[] parameters // are assigned with CONSTANT, which would not be correct. (After feature supported) diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 2834550282..059ddf3471 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -344,6 +344,16 @@ ETSFunctionType *ETSChecker::CreateETSFunctionType(ir::ScriptFunction *func, Sig return Allocator()->New(name, signature, Allocator()); } +ETSFunctionType *ETSChecker::CreateETSFunctionType(ir::ScriptFunction *func, ArenaVector &&signatures, + util::StringView name) +{ + if (func->IsDynamic()) { + return Allocator()->New(this, name, std::move(signatures), func->Language()); + } + + return Allocator()->New(this, name, std::move(signatures)); +} + Signature *ETSChecker::CreateSignature(SignatureInfo *info, Type *returnType, ir::ScriptFunction *func) { return Allocator()->New(info, returnType, func); @@ -650,8 +660,14 @@ ETSObjectType *ETSChecker::FunctionTypeToFunctionalInterfaceType(Signature *sign return functionN->Substitute(Relation(), substitution); } + // Note: FunctionN is not supported yet + if (signature->Params().size() >= GetGlobalTypesHolder()->VariadicFunctionTypeThreshold()) { + return nullptr; + } + auto *funcIface = GlobalBuiltinFunctionType(signature->Params().size())->AsETSObjectType(); auto *substitution = NewSubstitution(); + for (size_t i = 0; i < signature->Params().size(); i++) { substitution->emplace(funcIface->TypeArguments()[i]->AsETSTypeParameter(), MaybePromotedBuiltinType(signature->Params()[i]->TsType())); @@ -661,4 +677,13 @@ ETSObjectType *ETSChecker::FunctionTypeToFunctionalInterfaceType(Signature *sign return funcIface->Substitute(Relation(), substitution); } +Type *ETSChecker::ResolveFunctionalInterfaces(ArenaVector &signatures) +{ + ArenaVector types(Allocator()->Adapter()); + for (auto *signature : signatures) { + types.push_back(FunctionTypeToFunctionalInterfaceType(signature)); + } + return CreateETSUnionType(std::move(types)); +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsDynamicFunctionType.h b/ets2panda/checker/types/ets/etsDynamicFunctionType.h index 6aa4f2ec65..4f85f438f0 100644 --- a/ets2panda/checker/types/ets/etsDynamicFunctionType.h +++ b/ets2panda/checker/types/ets/etsDynamicFunctionType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. + * 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 @@ -18,11 +18,19 @@ #include "checker/types/ets/etsFunctionType.h" #include "checker/types/signature.h" +#include "checker/ETSchecker.h" namespace ark::es2panda::checker { class ETSDynamicFunctionType : public ETSFunctionType { public: + explicit ETSDynamicFunctionType(ETSChecker *checker, util::StringView name, ArenaVector &&signatures, + Language lang) + : ETSFunctionType(checker, name, std::move(signatures)), lang_(lang) + { + AddTypeFlag(TypeFlag::ETS_DYNAMIC_FUNCTION_TYPE); + } + explicit ETSDynamicFunctionType(util::StringView name, Signature *signature, ArenaAllocator *allocator, Language lang) : ETSFunctionType(name, signature, allocator), lang_(lang) diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index dce79be60a..8b8902ac5f 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -22,6 +22,14 @@ namespace ark::es2panda::checker { +ETSFunctionType::ETSFunctionType(ETSChecker *checker, util::StringView name, ArenaVector &&signatures) + : Type(TypeFlag::FUNCTION), + callSignatures_(std::move(signatures)), + name_(name), + funcInterface_(checker->ResolveFunctionalInterfaces(callSignatures_)) +{ +} + Signature *ETSFunctionType::FirstAbstractSignature() { for (auto *it : callSignatures_) { diff --git a/ets2panda/checker/types/ets/etsFunctionType.h b/ets2panda/checker/types/ets/etsFunctionType.h index 17fcb418c5..1740d445c6 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.h +++ b/ets2panda/checker/types/ets/etsFunctionType.h @@ -24,14 +24,15 @@ namespace ark::es2panda::checker { class ETSFunctionType : public Type { public: + explicit ETSFunctionType(ETSChecker *checker, util::StringView name, ArenaVector &&signatures); + explicit ETSFunctionType(util::StringView name, Signature *signature, ArenaAllocator *allocator) - : Type(TypeFlag::FUNCTION), callSignatures_(allocator->Adapter()), name_(name) + : Type(TypeFlag::FUNCTION), callSignatures_(allocator->Adapter()), name_(name), funcInterface_(nullptr) { callSignatures_.push_back(signature); } - explicit ETSFunctionType(util::StringView name, ArenaAllocator *allocator) - : Type(TypeFlag::FUNCTION), callSignatures_(allocator->Adapter()), name_(name) + : Type(TypeFlag::FUNCTION), callSignatures_(allocator->Adapter()), name_(name), funcInterface_(nullptr) { } @@ -50,6 +51,11 @@ public: return name_; } + Type *FunctionalInterface() const + { + return funcInterface_; + } + void AddCallSignature(Signature *signature) { if (signature->Function()->IsGetter()) { @@ -103,7 +109,7 @@ public: void ToAssemblerType([[maybe_unused]] std::stringstream &ss) const override { - UNREACHABLE(); + funcInterface_->ToAssemblerType(ss); } void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override @@ -126,6 +132,7 @@ private: ArenaVector callSignatures_; util::StringView name_; Signature *refSignature_ {}; + Type *const funcInterface_; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/test/parser/ets/FunctionalTypeAsArrayElement-expected.txt b/ets2panda/test/parser/ets/FunctionalTypeAsArrayElement-expected.txt new file mode 100644 index 0000000000..fe42426f87 --- /dev/null +++ b/ets2panda/test/parser/ets/FunctionalTypeAsArrayElement-expected.txt @@ -0,0 +1,528 @@ +{ + "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": "main", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "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": 16, + "column": 10 + }, + "end": { + "line": 16, + "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": "ETSFunctionType", + "params": [], + "returnType": { + "type": "TSArrayType", + "elementType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 10 + } + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 19, + "column": 6 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$trigger_cctor$_", + "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": "_$trigger_cctor$_", + "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": 22, + "column": 1 + } + } +} +TypeError: Type '(() => int)[]' cannot be assigned to type '() => int[]' [FunctionalTypeAsArrayElement.sts:17:24] diff --git a/ets2panda/test/parser/ets/FunctionalTypeAsArrayElement.sts b/ets2panda/test/parser/ets/FunctionalTypeAsArrayElement.sts new file mode 100644 index 0000000000..14473fcb47 --- /dev/null +++ b/ets2panda/test/parser/ets/FunctionalTypeAsArrayElement.sts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +function main(){ + let x: ()=>int[] = [ + ():int =>{return 1} + ] +} + diff --git a/ets2panda/test/runtime/ets/FunctionalTypeAsArrayElement.sts b/ets2panda/test/runtime/ets/FunctionalTypeAsArrayElement.sts new file mode 100644 index 0000000000..6c472dea59 --- /dev/null +++ b/ets2panda/test/runtime/ets/FunctionalTypeAsArrayElement.sts @@ -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. + */ + +function main(){ + let x: (()=>int)[] = [ + ():int =>{return 1}, + ():int =>{return 2} + ] + assert x[0]()==1 + assert x[1]()==2 +} + -- Gitee