diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 810934b8e53e9efea986fc479d2259ee75030a99..050613b400bb00256597a509fd973177485af8ff 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -411,57 +411,50 @@ checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const { ETSChecker *checker = GetETSChecker(); - checker->CreateFunctionalInterfaceForFunctionType(node); - auto *interfaceType = - checker->CreateETSObjectType(node->FunctionalInterface()->Id()->Name(), node->FunctionalInterface(), - checker::ETSObjectFlags::FUNCTIONAL_INTERFACE); - interfaceType->SetSuperType(checker->GlobalETSObjectType()); - - auto *invokeFunc = node->FunctionalInterface()->Body()->Body()[0]->AsMethodDefinition()->Function(); - auto *signatureInfo = checker->Allocator()->New(checker->Allocator()); - - for (auto *it : invokeFunc->Params()) { - auto *const param = it->AsETSParameterExpression(); - if (param->IsRestParameter()) { - auto *restIdent = param->Ident(); - - ASSERT(restIdent->Variable()); - signatureInfo->restVar = restIdent->Variable()->AsLocalVariable(); - - ASSERT(param->TypeAnnotation()); - signatureInfo->restVar->SetTsType(checker->GetTypeFromTypeAnnotation(param->TypeAnnotation())); - - auto arrayType = signatureInfo->restVar->TsType()->AsETSArrayType(); - checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); - } else { - auto *paramIdent = param->Ident(); - - ASSERT(paramIdent->Variable()); - varbinder::Variable *paramVar = paramIdent->Variable(); + auto *genericInterfaceType = checker->GlobalBuiltinFunctionType(node->Params().size()); + node->SetFunctionalInterface(genericInterfaceType->GetDeclNode()->AsTSInterfaceDeclaration()); + + auto *tsType = checker->GetCachedFunctionlInterface(node); + node->SetTsType(tsType); + if (tsType != nullptr) { + return tsType; + } + + auto *substitution = checker->NewSubstitution(); + + auto maxParamsNum = checker->GlobalBuiltinFunctionTypeVariadicThreshold(); + + auto const ¶ms = node->Params(); + size_t i = 0; + if (params.size() < maxParamsNum) { + for (; i < params.size(); i++) { + auto *paramType = + checker->GetTypeFromTypeAnnotation(params[i]->AsETSParameterExpression()->TypeAnnotation()); + if (paramType->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + checker->Relation()->SetNode(params[i]); + auto *const boxedTypeArg = checker->PrimitiveTypeAsETSBuiltinType(paramType); + ASSERT(boxedTypeArg); + paramType = boxedTypeArg->Instantiate(checker->Allocator(), checker->Relation(), + checker->GetGlobalTypesHolder()); + } - ASSERT(param->TypeAnnotation()); - paramVar->SetTsType(checker->GetTypeFromTypeAnnotation(param->TypeAnnotation())); - signatureInfo->params.push_back(paramVar->AsLocalVariable()); - ++signatureInfo->minArgCount; + checker::ETSChecker::EmplaceSubstituted( + substitution, genericInterfaceType->TypeArguments()[i]->AsETSTypeParameter()->GetOriginal(), paramType); } } - invokeFunc->ReturnTypeAnnotation()->Check(checker); - auto *signature = - checker->Allocator()->New(signatureInfo, node->ReturnType()->GetType(checker), invokeFunc); - signature->SetOwnerVar(invokeFunc->Id()->Variable()->AsLocalVariable()); - signature->AddSignatureFlag(checker::SignatureFlags::FUNCTIONAL_INTERFACE_SIGNATURE); - signature->SetOwner(interfaceType); + auto *returnType = node->ReturnType()->GetType(checker); + if (returnType->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + checker->Relation()->SetNode(node->ReturnType()); + auto *const boxedTypeRet = checker->PrimitiveTypeAsETSBuiltinType(returnType); + returnType = + boxedTypeRet->Instantiate(checker->Allocator(), checker->Relation(), checker->GetGlobalTypesHolder()); + } - auto *funcType = checker->CreateETSFunctionType(signature); - invokeFunc->SetSignature(signature); - invokeFunc->Id()->Variable()->SetTsType(funcType); - interfaceType->AddProperty(invokeFunc->Id()->Variable()->AsLocalVariable()); - node->FunctionalInterface()->SetTsType(interfaceType); + checker::ETSChecker::EmplaceSubstituted( + substitution, genericInterfaceType->TypeArguments()[i]->AsETSTypeParameter()->GetOriginal(), returnType); - auto *thisVar = invokeFunc->Scope()->ParamScope()->Params().front(); - thisVar->SetTsType(interfaceType); - checker->BuildFunctionalInterfaceName(node); + auto *interfaceType = genericInterfaceType->Substitute(checker->Relation(), substitution)->AsETSObjectType(); node->SetTsType(interfaceType); return interfaceType; @@ -1016,7 +1009,7 @@ ArenaVector &ChooseSignatures(ETSChecker *checker, checker } if (isFunctionalInterface) { return calleeType->AsETSObjectType() - ->GetOwnProperty("invoke") + ->GetOwnProperty(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME) ->TsType() ->AsETSFunctionType() ->CallSignatures(); diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 834464fcb7aeca39c4c8fd21343bc27fcfbbeafd..e111deca283261984ec8a3535eb1ddf976042dc0 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -29,6 +29,73 @@ #include "util/helpers.h" namespace panda::es2panda::checker { + +static util::StringView InitBuiltin(ETSChecker *checker, std::string_view signature) +{ + const auto varMap = checker->VarBinder()->TopScope()->Bindings(); + const auto iterator = varMap.find(signature); + ASSERT(iterator != varMap.end()); + auto *var = iterator->second; + Type *type {nullptr}; + if (var->Declaration()->Node()->IsClassDefinition()) { + type = checker->BuildBasicClassProperties(var->Declaration()->Node()->AsClassDefinition()); + } else { + ASSERT(var->Declaration()->Node()->IsTSInterfaceDeclaration()); + type = checker->BuildBasicInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); + } + checker->GetGlobalTypesHolder()->InitializeBuiltin(iterator->first, type); + return iterator->first; +} + +static void SetupFunctionalInterface(ETSChecker *checker, ETSObjectType *type) +{ + auto savedContext = SavedCheckerContext(checker, checker::CheckerStatus::IN_INTERFACE, type); + checker::ScopeContext scopeCtx(checker, type->GetDeclNode()->Scope()); + checker->ResolveDeclaredMembersOfObject(type); + type->AddObjectFlag(ETSObjectFlags::FUNCTIONAL); + auto *invoke = type->GetOwnProperty(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME); + auto *invokeType = invoke->TsType()->AsETSFunctionType(); + ASSERT(invokeType->CallSignatures().size() == 1); + auto *signature = invokeType->CallSignatures()[0]; + signature->AddSignatureFlag(SignatureFlags::FUNCTIONAL_INTERFACE_SIGNATURE); +} + +static void SetupBuiltinMember(ETSChecker *checker, varbinder::Variable *var) +{ + auto *type = var->TsType(); + if (type == nullptr || !type->IsETSObjectType()) { + return; + } + auto *objType = type->AsETSObjectType(); + auto *declNode = var->Declaration()->Node(); + if (declNode->IsClassDefinition()) { + auto savedContext = SavedCheckerContext(checker, checker::CheckerStatus::IN_CLASS, objType); + checker::ScopeContext scopeCtx(checker, declNode->Scope()); + checker->ResolveDeclaredMembersOfObject(objType); + } else if (declNode->IsTSInterfaceDeclaration()) { + auto savedContext = SavedCheckerContext(checker, checker::CheckerStatus::IN_INTERFACE, objType); + checker::ScopeContext scopeCtx(checker, declNode->Scope()); + checker->ResolveDeclaredMembersOfObject(objType); + } +} + +// NOLINTNEXTLINE(modernize-avoid-c-arrays) +static constexpr std::string_view BUILTINS_TO_INIT[] = { + compiler::Signatures::BUILTIN_BOOLEAN_CLASS, compiler::Signatures::BUILTIN_BYTE_CLASS, + compiler::Signatures::BUILTIN_CHAR_CLASS, compiler::Signatures::BUILTIN_SHORT_CLASS, + compiler::Signatures::BUILTIN_INT_CLASS, compiler::Signatures::BUILTIN_LONG_CLASS, + compiler::Signatures::BUILTIN_FLOAT_CLASS, compiler::Signatures::BUILTIN_DOUBLE_CLASS, + compiler::Signatures::BUILTIN_FUNCTION0_CLASS, compiler::Signatures::BUILTIN_FUNCTION1_CLASS, + compiler::Signatures::BUILTIN_FUNCTION2_CLASS, compiler::Signatures::BUILTIN_FUNCTION3_CLASS, + compiler::Signatures::BUILTIN_FUNCTION4_CLASS, compiler::Signatures::BUILTIN_FUNCTION5_CLASS, + compiler::Signatures::BUILTIN_FUNCTION6_CLASS, compiler::Signatures::BUILTIN_FUNCTION7_CLASS, + compiler::Signatures::BUILTIN_FUNCTION8_CLASS, compiler::Signatures::BUILTIN_FUNCTION9_CLASS, + compiler::Signatures::BUILTIN_FUNCTION10_CLASS, compiler::Signatures::BUILTIN_FUNCTION11_CLASS, + compiler::Signatures::BUILTIN_FUNCTION12_CLASS, compiler::Signatures::BUILTIN_FUNCTION13_CLASS, + compiler::Signatures::BUILTIN_FUNCTION14_CLASS, compiler::Signatures::BUILTIN_FUNCTION15_CLASS, + compiler::Signatures::BUILTIN_FUNCTION16_CLASS, compiler::Signatures::BUILTIN_FUNCTIONN_CLASS, +}; + void ETSChecker::InitializeBuiltins(varbinder::ETSBinder *varbinder) { if (HasStatus(CheckerStatus::BUILTINS_INITIALIZED)) { @@ -37,17 +104,23 @@ void ETSChecker::InitializeBuiltins(varbinder::ETSBinder *varbinder) const auto varMap = varbinder->TopScope()->Bindings(); - auto initBuiltin = [varMap](ETSChecker *checker, std::string_view signature) -> util::StringView { - const auto iterator = varMap.find(signature); - ASSERT(iterator != varMap.end()); - checker->GetGlobalTypesHolder()->InitializeBuiltin( - iterator->first, - checker->BuildClassProperties(iterator->second->Declaration()->Node()->AsClassDefinition())); - return iterator->first; - }; + auto const objectName = InitBuiltin(this, compiler::Signatures::BUILTIN_OBJECT_CLASS); + auto const voidName = InitBuiltin(this, compiler::Signatures::BUILTIN_VOID_CLASS); + + for (auto sig : BUILTINS_TO_INIT) { + InitBuiltin(this, sig); + } - auto const objectName = initBuiltin(this, compiler::Signatures::BUILTIN_OBJECT_CLASS); - auto const voidName = initBuiltin(this, compiler::Signatures::BUILTIN_VOID_CLASS); + for (size_t id = static_cast(GlobalTypeId::ETS_FUNCTION0_CLASS), nargs = 0; + id <= static_cast(GlobalTypeId::ETS_FUNCTIONN_CLASS); id++, nargs++) { + auto *type = GetGlobalTypesHolder()->GlobalFunctionBuiltinType(nargs)->AsETSObjectType(); + SetupFunctionalInterface(this, type); + } + + for (const auto &[name, var] : varMap) { + (void)name; + SetupBuiltinMember(this, var); + } for (const auto &[name, var] : varMap) { if (name == objectName || name == voidName) { @@ -55,7 +128,11 @@ void ETSChecker::InitializeBuiltins(varbinder::ETSBinder *varbinder) } if (var->HasFlag(varbinder::VariableFlags::BUILTIN_TYPE)) { - InitializeBuiltin(var, name); + if (var->TsType() == nullptr) { + InitializeBuiltin(var, name); + } else { + GetGlobalTypesHolder()->InitializeBuiltin(name, var->TsType()); + } } } @@ -160,9 +237,10 @@ Type *ETSChecker::CheckTypeCached(ir::Expression *expr) return expr->TsType(); } -ETSObjectType *ETSChecker::AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)()) const +template +ETSObjectType *ETSChecker::AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const { - auto *ret = (GetGlobalTypesHolder()->*typeFunctor)(); + auto *ret = (GetGlobalTypesHolder()->*typeFunctor)(args...); return ret != nullptr ? ret->AsETSObjectType() : nullptr; } @@ -296,6 +374,16 @@ ETSObjectType *ETSChecker::GlobalBuiltinVoidType() const return AsETSObjectType(&GlobalTypesHolder::GlobalBuiltinVoidType); } +ETSObjectType *ETSChecker::GlobalBuiltinFunctionType(size_t nargs) const +{ + return AsETSObjectType(&GlobalTypesHolder::GlobalFunctionBuiltinType, nargs); +} + +size_t ETSChecker::GlobalBuiltinFunctionTypeVariadicThreshold() const +{ + return GetGlobalTypesHolder()->VariadicFunctionTypeThreshold(); +} + ETSObjectType *ETSChecker::GlobalBuiltinDynamicType(Language lang) const { if (lang.GetId() == Language::Id::JS) { diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index e909286f9379778b42a2def9136e029356ee7fb0..710021b70fbeb4d7124d3a520d3766c48fa1a8ab 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -63,6 +63,7 @@ using ArrayMap = ArenaUnorderedMap; using GlobalArraySignatureMap = ArenaUnorderedMap; using DynamicCallIntrinsicsMap = ArenaUnorderedMap>; using DynamicLambdaObjectSignatureMap = ArenaUnorderedMap; +using FunctionalInterfaceMap = ArenaUnorderedMap; class ETSChecker final : public Checker { public: @@ -75,7 +76,8 @@ public: cachedComputedAbstracts_(Allocator()->Adapter()), dynamicCallIntrinsics_(Allocator()->Adapter()), dynamicNewIntrinsics_(Allocator()->Adapter()), - dynamicLambdaSignatureCache_(Allocator()->Adapter()) + dynamicLambdaSignatureCache_(Allocator()->Adapter()), + functionalInterfaceCache_(Allocator()->Adapter()) { } @@ -118,6 +120,9 @@ public: ETSObjectType *GlobalBuiltinBoxType(const Type *contents) const; ETSObjectType *GlobalBuiltinVoidType() const; + ETSObjectType *GlobalBuiltinFunctionType(size_t nargs) const; + size_t GlobalBuiltinFunctionTypeVariadicThreshold() const; + ETSObjectType *GlobalBuiltinDynamicType(Language lang) const; const checker::WrapperDesc &PrimitiveWrapper() const; @@ -140,8 +145,10 @@ public: } // Object + ETSObjectType *BuildBasicClassProperties(ir::ClassDefinition *classDef); ETSObjectType *BuildClassProperties(ir::ClassDefinition *classDef); ETSObjectType *BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType); + ETSObjectType *BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl); ETSObjectType *BuildInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl); ETSObjectType *GetSuperType(ETSObjectType *type); ArenaVector GetInterfaces(ETSObjectType *type); @@ -395,7 +402,7 @@ public: ArenaVector &properties); std::tuple CreateLambdaCtorImplicitParam( ArenaVector ¶ms, const lexer::SourceRange &pos, bool isStaticReference); - ir::MethodDefinition *CreateLambdaInvokeProto(); + ir::MethodDefinition *CreateLambdaInvokeProto(util::StringView invokeName); void CreateLambdaFuncDecl(ir::MethodDefinition *func, varbinder::LocalScope *scope); void ResolveProxyMethod(ir::MethodDefinition *proxyMethod, ir::ArrowFunctionExpression *lambda); void ResolveLambdaObject(ir::ClassDefinition *lambdaObject, Signature *signature, @@ -404,18 +411,18 @@ public: ir::ArrowFunctionExpression *lambda, ir::MethodDefinition *proxyMethod, bool saveThis); void ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject, bool isStaticReference); void ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject); - void ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Signature *signatureRef); + void ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Signature *signatureRef, bool ifaceOverride); void ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, ir::ArrowFunctionExpression *lambda, - ir::MethodDefinition *proxyMethod, bool isStatic); - ir::Statement *ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambdaObject, Signature *signatureRef); + ir::MethodDefinition *proxyMethod, bool isStatic, bool ifaceOverride); + ir::Statement *ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambdaObject, Signature *signatureRef, + bool ifaceOverride); ir::Statement *ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambdaObject, - ir::MethodDefinition *proxyMethod, bool isStatic); - void CreateFunctionalInterfaceForFunctionType(ir::ETSFunctionType *funcType); - ir::MethodDefinition *CreateInvokeFunction(ir::ETSFunctionType *funcType); + ir::ArrowFunctionExpression *lambda, + ir::MethodDefinition *proxyMethod, bool isStatic, + bool ifaceOverride); void CheckCapturedVariables(); void CheckCapturedVariableInSubnodes(ir::AstNode *node, varbinder::Variable *var); void CheckCapturedVariable(ir::AstNode *node, varbinder::Variable *var); - void BuildFunctionalInterfaceName(ir::ETSFunctionType *funcType); void CreateAsyncProxyMethods(ir::ClassDefinition *classDef); ir::MethodDefinition *CreateAsyncImplMethod(ir::MethodDefinition *asyncMethod, ir::ClassDefinition *classDef); ir::MethodDefinition *CreateAsyncProxy(ir::MethodDefinition *asyncMethod, ir::ClassDefinition *classDef, @@ -537,6 +544,7 @@ public: ETSObjectType *GetRelevantArgumentedTypeFromChild(ETSObjectType *child, ETSObjectType *target); util::StringView GetHashFromTypeArguments(const ArenaVector &typeArgTypes); util::StringView GetHashFromSubstitution(const Substitution *substitution); + util::StringView GetHashFromFunctionType(ir::ETSFunctionType *type); ETSObjectType *GetOriginalBaseType(Type *object); Type *GetTypeFromTypeAnnotation(ir::TypeNode *typeAnnotation); void AddUndefinedParamsForDefaultParams(const Signature *signature, @@ -549,9 +557,8 @@ public: Type *SelectGlobalIntegerTypeForNumeric(Type *type); const Type *TryGettingFunctionTypeFromInvokeFunction(const Type *type) const; - void GenerateGetterSetterBody(ETSChecker *checker, ArenaVector &stmts, - ArenaVector ¶ms, ir::ClassProperty *field, - varbinder::FunctionParamScope *paramScope, bool isSetter); + void GenerateGetterSetterBody(ArenaVector &stmts, ArenaVector ¶ms, + ir::ClassProperty *field, varbinder::FunctionParamScope *paramScope, bool isSetter); static ir::MethodDefinition *GenerateDefaultGetterSetter(ir::ClassProperty *field, varbinder::ClassScope *scope, bool isSetter, ETSChecker *checker); @@ -610,6 +617,9 @@ public: return ret; } + ETSObjectType *GetCachedFunctionlInterface(ir::ETSFunctionType *type); + void CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectType *ifaceType); + private: using ClassBuilder = std::function *)>; using ClassInitializerBuilder = std::function *, @@ -688,7 +698,8 @@ private: template typename TargetType::UType GetOperand(Type *type); - ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)()) const; + template + ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const; Signature *GetMostSpecificSignature(ArenaVector &compatibleSignatures, ArenaVector &proxySignatures, const ArenaVector &arguments, @@ -713,6 +724,7 @@ private: DynamicCallIntrinsicsMap dynamicCallIntrinsics_; DynamicCallIntrinsicsMap dynamicNewIntrinsics_; DynamicLambdaObjectSignatureMap dynamicLambdaSignatureCache_; + FunctionalInterfaceMap functionalInterfaceCache_; std::recursive_mutex mtx_; }; diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index e6476c47e5aa9b87ce662392da988ef5231198fc..9dffd8fd254227c154f7ab44b72aab4dff686986 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -20,6 +20,7 @@ #include "varbinder/variable.h" #include "varbinder/variableFlags.h" #include "checker/ETSchecker.h" +#include "checker/ets/castingContext.h" #include "checker/ets/function_helpers.h" #include "checker/ets/typeRelationContext.h" #include "checker/types/ets/etsAsyncFuncReturnType.h" @@ -143,10 +144,12 @@ bool ETSChecker::EnhanceSubstitutionForObject(const ArenaVector &typePar } if (argumentType->IsETSFunctionType() && paramObjType->HasObjectFlag(ETSObjectFlags::FUNCTIONAL_INTERFACE)) { - auto ¶meterSignatures = paramObjType->GetOwnProperty("invoke") - ->TsType() - ->AsETSFunctionType() - ->CallSignatures(); + auto ¶meterSignatures = + paramObjType + ->GetOwnProperty(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME) + ->TsType() + ->AsETSFunctionType() + ->CallSignatures(); auto &argumentSignatures = argumentType->AsETSFunctionType()->CallSignatures(); ASSERT(argumentSignatures.size() == 1); ASSERT(parameterSignatures.size() == 1); @@ -1405,83 +1408,53 @@ void ETSChecker::CheckCapturedVariables() } } -void ETSChecker::BuildFunctionalInterfaceName(ir::ETSFunctionType *funcType) -{ - VarBinder()->AsETSBinder()->BuildFunctionalInterfaceName(funcType); -} +// Lambda creation for Lambda expressions -void ETSChecker::CreateFunctionalInterfaceForFunctionType(ir::ETSFunctionType *funcType) +// Chunk pulled out of CreateLambdaObjectForLambdaReference to appease Chinese code checker +static std::pair, bool> CreateLambdaObjectPropertiesForLambdaReference( + ETSChecker *checker, ir::ArrowFunctionExpression *lambda, varbinder::ClassScope *classScope) { - auto *identNode = Allocator()->New(util::StringView("FunctionalInterface"), Allocator()); - - auto interfaceCtx = varbinder::LexicalScope(VarBinder()); - auto *interfaceScope = interfaceCtx.GetScope(); - - ArenaVector members(Allocator()->Adapter()); - ir::MethodDefinition *invokeFunc = CreateInvokeFunction(funcType); - members.push_back(invokeFunc); - - auto methodCtx = - varbinder::LexicalScope::Enter(VarBinder(), interfaceScope->InstanceMethodScope()); - auto [_, var] = VarBinder()->NewVarDecl(invokeFunc->Start(), Allocator(), - invokeFunc->Id()->Name(), invokeFunc); - (void)_; - var->AddFlag(varbinder::VariableFlags::METHOD); - invokeFunc->Function()->Id()->SetVariable(var); + bool saveThis = false; + size_t idx = 0; + const auto &capturedVars = lambda->CapturedVars(); - if (funcType->IsThrowing()) { - invokeFunc->Function()->AddFlag(ir::ScriptFunctionFlags::THROWS); + // Create the synthetic class property nodes for the captured variables + ArenaVector properties(checker->Allocator()->Adapter()); + for (const auto *it : capturedVars) { + if (it->HasFlag(varbinder::VariableFlags::LOCAL)) { + properties.push_back(checker->CreateLambdaCapturedField(it, classScope, idx, lambda->Start())); + idx++; + } else if (!it->HasFlag(varbinder::VariableFlags::STATIC) && + !checker->Context().ContainingClass()->HasObjectFlag(ETSObjectFlags::GLOBAL)) { + saveThis = true; + } } - auto *body = Allocator()->New(std::move(members)); - - ArenaVector extends(Allocator()->Adapter()); - auto *interfaceDecl = Allocator()->New( - Allocator(), identNode, nullptr, body, std::move(extends), false, false, Language(Language::Id::ETS)); - interfaceDecl->SetScope(interfaceScope); - interfaceDecl->AddModifier(ir::ModifierFlags::FUNCTIONAL); - funcType->SetFunctionalInterface(interfaceDecl); - invokeFunc->SetParent(interfaceDecl); + // If the lambda captured a property in the current class, we have to make a synthetic class property to store + // 'this' in it + if (saveThis) { + properties.push_back(checker->CreateLambdaCapturedThis(classScope, idx, lambda->Start())); + idx++; + } - VarBinder()->AsETSBinder()->BuildFunctionType(funcType); + return {properties, saveThis}; } -ir::MethodDefinition *ETSChecker::CreateInvokeFunction(ir::ETSFunctionType *funcType) +static void HandleAsyncFuncInLambda(ETSChecker *checker, ir::ArrowFunctionExpression *lambda, + ir::MethodDefinition *proxyMethod, ir::ClassDefinition *currentClassDef) { - auto *identNode = Allocator()->New(util::StringView("invoke"), Allocator()); - - ArenaVector params(Allocator()->Adapter()); - auto *funcParamScope = CopyParams(funcType->Params(), params); - - auto paramCtx = varbinder::LexicalScope::Enter(VarBinder(), funcParamScope, false); - auto functionCtx = varbinder::LexicalScope(VarBinder()); - auto *functionScope = functionCtx.GetScope(); - functionScope->BindParamScope(funcParamScope); - funcParamScope->BindFunctionScope(functionScope); - - ir::ModifierFlags flags = ir::ModifierFlags::ABSTRACT | ir::ModifierFlags::PUBLIC; - auto *func = Allocator()->New( - ir::FunctionSignature(nullptr, std::move(params), funcType->ReturnType()), nullptr, - ir::ScriptFunctionFlags::METHOD, flags, false, Language(Language::Id::ETS)); - - func->SetScope(functionScope); - functionScope->BindNode(func); - funcParamScope->BindNode(func); - - auto *funcExpr = Allocator()->New(func); - func->SetIdent(identNode); - - auto *method = Allocator()->New(ir::MethodDefinitionKind::METHOD, identNode, funcExpr, flags, - Allocator(), false); - - funcExpr->SetParent(method); - func->SetParent(funcExpr); - - return method; + ir::MethodDefinition *asyncImpl = checker->CreateAsyncProxy(proxyMethod, currentClassDef); + ir::ScriptFunction *asyncImplFunc = asyncImpl->Function(); + currentClassDef->Body().push_back(asyncImpl); + asyncImpl->SetParent(currentClassDef); + checker->ReplaceIdentifierReferencesInProxyMethod(asyncImplFunc->Body(), asyncImplFunc->Params(), + lambda->Function()->Params(), lambda->CapturedVars()); + Signature *implSig = checker->CreateSignature(proxyMethod->Function()->Signature()->GetSignatureInfo(), + checker->GlobalETSObjectType(), asyncImplFunc); + asyncImplFunc->SetSignature(implSig); + checker->VarBinder()->AsETSBinder()->BuildFunctionName(asyncImpl->Function()); } -// Lambda creation for Lambda expressions - void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpression *lambda, ETSObjectType *functionalInterface) { @@ -1489,33 +1462,12 @@ void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpressio return; } - bool saveThis = false; - size_t idx = 0; - const auto &capturedVars = lambda->CapturedVars(); - auto *currentClassDef = Context().ContainingClass()->GetDeclNode()->AsClassDefinition(); - // Create the class scope for the synthetic lambda class node auto classCtx = varbinder::LexicalScope(VarBinder()); auto *classScope = classCtx.GetScope(); - // Create the synthetic class property nodes for the captured variables - ArenaVector properties(Allocator()->Adapter()); - for (const auto *it : capturedVars) { - if (it->HasFlag(varbinder::VariableFlags::LOCAL)) { - properties.push_back(CreateLambdaCapturedField(it, classScope, idx, lambda->Start())); - idx++; - } else if (!it->HasFlag(varbinder::VariableFlags::STATIC) && - !Context().ContainingClass()->HasObjectFlag(ETSObjectFlags::GLOBAL)) { - saveThis = true; - } - } - - // If the lambda captured a property in the current class, we have to make a synthetic class property to store - // 'this' in it - if (saveThis) { - properties.push_back(CreateLambdaCapturedThis(classScope, idx, lambda->Start())); - idx++; - } + auto [properties, saveThis] = CreateLambdaObjectPropertiesForLambdaReference(this, lambda, classScope); + auto *currentClassDef = Context().ContainingClass()->GetDeclNode()->AsClassDefinition(); // Create the synthetic proxy method node for the current class definiton, which we will use in the lambda // 'invoke' method to propagate the function call to the current class @@ -1526,16 +1478,18 @@ void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpressio properties.push_back(ctor); // Create the synthetic invoke node for the lambda class, which will propagate the call to the proxy method - auto *invokeFunc = CreateLambdaInvokeProto(); + auto *invoke0Func = CreateLambdaInvokeProto(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME); + auto *invokeFunc = CreateLambdaInvokeProto("invoke"); + properties.push_back(invoke0Func); properties.push_back(invokeFunc); // Create the declarations for the synthetic constructor and invoke method CreateLambdaFuncDecl(ctor, classScope->StaticMethodScope()); + CreateLambdaFuncDecl(invoke0Func, classScope->InstanceMethodScope()); CreateLambdaFuncDecl(invokeFunc, classScope->InstanceMethodScope()); // Create the synthetic lambda class node - ArenaVector implements(Allocator()->Adapter()); auto *identNode = Allocator()->New(util::StringView("LambdaObject"), Allocator()); auto *lambdaObject = Allocator()->New(Allocator(), identNode, std::move(properties), @@ -1553,6 +1507,7 @@ void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpressio // Set the parent nodes ctor->SetParent(lambdaObject); + invoke0Func->SetParent(lambdaObject); invokeFunc->SetParent(lambdaObject); classScope->BindNode(lambdaObject); @@ -1562,15 +1517,7 @@ void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpressio // Resolve the proxy method ResolveProxyMethod(proxyMethod, lambda); if (lambda->Function()->IsAsyncFunc()) { - ir::MethodDefinition *asyncImpl = CreateAsyncProxy(proxyMethod, currentClassDef); - ir::ScriptFunction *asyncImplFunc = asyncImpl->Function(); - currentClassDef->Body().push_back(asyncImpl); - ReplaceIdentifierReferencesInProxyMethod(asyncImplFunc->Body(), asyncImplFunc->Params(), - lambda->Function()->Params(), lambda->CapturedVars()); - Signature *implSig = CreateSignature(proxyMethod->Function()->Signature()->GetSignatureInfo(), - GlobalETSObjectType(), asyncImplFunc); - asyncImplFunc->SetSignature(implSig); - VarBinder()->AsETSBinder()->BuildFunctionName(asyncImpl->Function()); + HandleAsyncFuncInLambda(this, lambda, proxyMethod, currentClassDef); } // Resolve the lambda object @@ -1608,45 +1555,75 @@ void ETSChecker::ResolveLambdaObject(ir::ClassDefinition *lambdaObject, ETSObjec ResolveLambdaObjectCtor(lambdaObject); // Resolve the invoke function - ResolveLambdaObjectInvoke(lambdaObject, lambda, proxyMethod, !saveThis); + ResolveLambdaObjectInvoke(lambdaObject, lambda, proxyMethod, !saveThis, true); + ResolveLambdaObjectInvoke(lambdaObject, lambda, proxyMethod, !saveThis, false); } -void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, ir::ArrowFunctionExpression *lambda, - ir::MethodDefinition *proxyMethod, bool isStatic) +static Signature *CreateInvokeSignature(ETSChecker *checker, ir::ArrowFunctionExpression *lambda, + ir::ScriptFunction *invokeFunc, ETSObjectType *lambdaObjectType, + bool ifaceOverride) { - const auto &lambdaBody = lambdaObject->Body(); - auto *invokeFunc = lambdaBody[lambdaBody.size() - 1]->AsMethodDefinition()->Function(); - ETSObjectType *lambdaObjectType = lambdaObject->TsType()->AsETSObjectType(); - - // Set the implicit 'this' parameters type to the lambda object - auto *thisVar = invokeFunc->Scope()->ParamScope()->Params().front(); - thisVar->SetTsType(lambdaObjectType); + auto *allocator = checker->Allocator(); // Create the signature for the invoke function type - auto *invokeSignatureInfo = CreateSignatureInfo(); + auto *invokeSignatureInfo = checker->CreateSignatureInfo(); invokeSignatureInfo->restVar = nullptr; // Create the parameters for the invoke function, based on the lambda function's parameters - for (auto *it : lambda->Function()->Params()) { + auto maxParamsNum = checker->GlobalBuiltinFunctionTypeVariadicThreshold(); + auto paramsNum = lambda->Function()->Params().size(); + if (paramsNum < maxParamsNum || !ifaceOverride) { + for (auto *it : lambda->Function()->Params()) { + auto paramCtx = varbinder::LexicalScope::Enter( + checker->VarBinder(), invokeFunc->Scope()->ParamScope(), false); + auto *const param = it->Clone(allocator, it->Parent())->AsETSParameterExpression(); + auto [_, var] = checker->VarBinder()->AddParamDecl(param); + (void)_; + var->SetTsType(ifaceOverride ? checker->GlobalETSNullishObjectType() : param->Variable()->TsType()); + param->Ident()->SetVariable(var); + invokeFunc->Params().push_back(param); + invokeSignatureInfo->minArgCount++; + invokeSignatureInfo->params.push_back(var->AsLocalVariable()); + } + } else { auto paramCtx = varbinder::LexicalScope::Enter( - VarBinder(), invokeFunc->Scope()->ParamScope(), false); + checker->VarBinder(), invokeFunc->Scope()->ParamScope(), false); - auto *const param = it->AsETSParameterExpression(); - auto [_, var] = VarBinder()->AddParamDecl(param); + auto *id = checker->AllocNode("p", allocator); + auto *restElement = checker->AllocNode(ir::AstNodeType::REST_ELEMENT, allocator, id); + auto *const param = checker->AllocNode(restElement, nullptr); + auto [_, var] = checker->VarBinder()->AddParamDecl(param); (void)_; - var->SetTsType(param->Variable()->TsType()); + var->SetTsType(checker->CreateETSArrayType(checker->GlobalETSNullishObjectType())); param->Ident()->SetVariable(var); invokeFunc->Params().push_back(param); - invokeSignatureInfo->minArgCount++; - invokeSignatureInfo->params.push_back(var->AsLocalVariable()); + invokeSignatureInfo->restVar = var->AsLocalVariable(); } // Create the function type for the invoke method - auto *invokeSignature = - CreateSignature(invokeSignatureInfo, lambda->Function()->Signature()->ReturnType(), invokeFunc); + auto *invokeSignature = checker->CreateSignature(invokeSignatureInfo, + ifaceOverride ? checker->GlobalETSNullishObjectType() + : lambda->Function()->Signature()->ReturnType(), + invokeFunc); invokeSignature->SetOwner(lambdaObjectType); invokeSignature->AddSignatureFlag(checker::SignatureFlags::CALL); + return invokeSignature; +} + +void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, ir::ArrowFunctionExpression *lambda, + ir::MethodDefinition *proxyMethod, bool isStatic, bool ifaceOverride) +{ + const auto &lambdaBody = lambdaObject->Body(); + auto *invokeFunc = lambdaBody[lambdaBody.size() - (ifaceOverride ? 2 : 1)]->AsMethodDefinition()->Function(); + ETSObjectType *lambdaObjectType = lambdaObject->TsType()->AsETSObjectType(); + + // Set the implicit 'this' parameters type to the lambda object + auto *thisVar = invokeFunc->Scope()->ParamScope()->Params().front(); + thisVar->SetTsType(lambdaObjectType); + + // Create the function type for the invoke method + auto *invokeSignature = CreateInvokeSignature(this, lambda, invokeFunc, lambdaObjectType, ifaceOverride); auto *invokeType = CreateETSFunctionType(invokeSignature); invokeFunc->SetSignature(invokeSignature); invokeFunc->Id()->Variable()->SetTsType(invokeType); @@ -1655,7 +1632,8 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, ir invokeFunc->Id()->Variable()->AsLocalVariable()); // Fill out the type information for the body of the invoke function - auto *resolvedLambdaInvokeFunctionBody = ResolveLambdaObjectInvokeFuncBody(lambdaObject, proxyMethod, isStatic); + auto *resolvedLambdaInvokeFunctionBody = + ResolveLambdaObjectInvokeFuncBody(lambdaObject, lambda, proxyMethod, isStatic, ifaceOverride); if (invokeFunc->IsAsyncFunc()) { return; } @@ -1665,8 +1643,90 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, ir } } +/* Pulled out to appease the Chinese checker */ + +static void AddFieldRefsToCallParameters(ETSChecker *checker, ir::ClassDefinition *lambdaObject, bool isStatic, + ArenaVector &callParams) +{ + auto *allocator = checker->Allocator(); + auto &lambdaBody = lambdaObject->Body(); + size_t counter = isStatic ? lambdaBody.size() - 3 : lambdaBody.size() - 4; + for (size_t i = 0; i < counter; i++) { + if (lambdaBody[i]->IsMethodDefinition()) { + break; + } + + auto *classProp = lambdaBody[i]->AsClassProperty(); + auto *param = allocator->New(classProp->Key()->AsIdentifier()->Name(), allocator); + param->SetVariable(classProp->Key()->AsIdentifier()->Variable()); + param->SetIgnoreBox(); + param->SetTsType(checker->MaybeBoxedType(param->Variable())); + callParams.push_back(param); + } +} + +static ArenaVector ResolveCallParametersForLambdaFuncBody(ETSChecker *checker, + ir::ClassDefinition *lambdaObject, + ir::ArrowFunctionExpression *lambda, + ir::ScriptFunction *invokeFunc, + bool isStatic, bool ifaceOverride) +{ + auto *allocator = checker->Allocator(); + ArenaVector callParams(allocator->Adapter()); + + AddFieldRefsToCallParameters(checker, lambdaObject, isStatic, callParams); + + auto maxParamsNum = checker->GlobalBuiltinFunctionTypeVariadicThreshold(); + auto paramsNum = lambda->Function()->Params().size(); + if (!ifaceOverride) { + for (auto const *const it : invokeFunc->Params()) { + auto const *const param = it->AsETSParameterExpression(); + auto *const paramIdent = allocator->New(param->Ident()->Name(), allocator); + paramIdent->SetVariable(param->Variable()); + paramIdent->SetTsType(param->Variable()->TsType()); + callParams.push_back(paramIdent); + } + } else if (paramsNum < maxParamsNum) { + // Then we add the lambda functions parameters to the call + auto nargs = invokeFunc->Params().size(); + for (size_t i = 0; i < nargs; i++) { + auto const *const param = invokeFunc->Params()[i]->AsETSParameterExpression(); + auto *const paramIdent = allocator->New(param->Ident()->Name(), allocator); + paramIdent->SetVariable(param->Variable()); + paramIdent->SetTsType(param->Variable()->TsType()); + + auto *lambdaParam = lambda->Function()->Params()[i]->AsETSParameterExpression(); + auto *const paramCast = + allocator->New(paramIdent, lambdaParam->TypeAnnotation(), false); + paramCast->Check(checker); + callParams.push_back(paramCast); + } + } else { + ASSERT(invokeFunc->Params().size() == 1); + auto const *const param = invokeFunc->Params()[0]->AsETSParameterExpression(); + auto *const paramIdent = allocator->New(param->Ident()->Name(), allocator); + paramIdent->SetVariable(param->Variable()); + paramIdent->SetTsType(param->Variable()->TsType()); + + for (size_t i = 0; i < paramsNum; i++) { + auto *idx = allocator->New(lexer::Number(static_cast(i))); + auto *arg = allocator->New(paramIdent, idx, ir::MemberExpressionKind::ELEMENT_ACCESS, + true, false); + + auto *lambdaParam = lambda->Function()->Params()[i]->AsETSParameterExpression(); + auto *const paramCast = allocator->New(arg, lambdaParam->TypeAnnotation(), false); + paramCast->Check(checker); + callParams.push_back(paramCast); + } + } + + return callParams; +} + ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambdaObject, - ir::MethodDefinition *proxyMethod, bool isStatic) + ir::ArrowFunctionExpression *lambda, + ir::MethodDefinition *proxyMethod, bool isStatic, + bool ifaceOverride) { const auto &lambdaBody = lambdaObject->Body(); auto *proxySignature = proxyMethod->Function()->Signature(); @@ -1681,7 +1741,7 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition fieldIdent->SetTsType(fieldPropType); } else { // Otherwise, we call the proxy method through the saved 'this' field - auto *savedThis = lambdaBody[lambdaBody.size() - 3]->AsClassProperty(); + auto *savedThis = lambdaBody[lambdaBody.size() - 4]->AsClassProperty(); auto *fieldProp = savedThis->Key()->AsIdentifier()->Variable(); fieldPropType = fieldProp->TsType()->AsETSObjectType(); fieldIdent = Allocator()->New(savedThis->Key()->AsIdentifier()->Name(), Allocator()); @@ -1698,30 +1758,9 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition callee->SetTsType(proxySignature->OwnerVar()->TsType()); // Resolve the proxy method call arguments, first we add the captured fields to the call - auto *invokeFunc = lambdaBody[lambdaBody.size() - 1]->AsMethodDefinition()->Function(); - ArenaVector callParams(Allocator()->Adapter()); - size_t counter = isStatic ? lambdaBody.size() - 2 : lambdaBody.size() - 3; - for (size_t i = 0; i < counter; i++) { - if (lambdaBody[i]->IsMethodDefinition()) { - break; - } - - auto *classProp = lambdaBody[i]->AsClassProperty(); - auto *param = Allocator()->New(classProp->Key()->AsIdentifier()->Name(), Allocator()); - param->SetVariable(classProp->Key()->AsIdentifier()->Variable()); - param->SetIgnoreBox(); - param->SetTsType(MaybeBoxedType(param->Variable())); - callParams.push_back(param); - } - - // Then we add the lambda functions parameters to the call - for (auto const *const it : invokeFunc->Params()) { - auto const *const param = it->AsETSParameterExpression(); - auto *const paramIdent = Allocator()->New(param->Ident()->Name(), Allocator()); - paramIdent->SetVariable(param->Variable()); - paramIdent->SetTsType(param->Variable()->TsType()); - callParams.push_back(paramIdent); - } + auto *invokeFunc = lambdaBody[lambdaBody.size() - (ifaceOverride ? 2 : 1)]->AsMethodDefinition()->Function(); + ArenaVector callParams = + ResolveCallParametersForLambdaFuncBody(this, lambdaObject, lambda, invokeFunc, isStatic, ifaceOverride); // Create the synthetic call expression to the proxy method auto *resolvedCall = Allocator()->New(callee, std::move(callParams), nullptr, false); @@ -1731,6 +1770,11 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition if (proxySignature->ReturnType()->IsETSVoidType()) { return Allocator()->New(resolvedCall); } + + if (ifaceOverride && resolvedCall->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + resolvedCall->AddBoxingUnboxingFlags(GetBoxingFlag(resolvedCall->TsType())); + } + return Allocator()->New(resolvedCall); } @@ -1738,7 +1782,7 @@ void ETSChecker::ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject) { const auto &lambdaBody = lambdaObject->Body(); auto *lambdaObjectType = lambdaObject->TsType()->AsETSObjectType(); - auto *ctorFunc = lambdaBody[lambdaBody.size() - 2]->AsMethodDefinition()->Function(); + auto *ctorFunc = lambdaBody[lambdaBody.size() - 3]->AsMethodDefinition()->Function(); // Set the implicit 'this' parameters type to the lambda object auto *thisVar = ctorFunc->Scope()->ParamScope()->Params().front(); @@ -2210,10 +2254,13 @@ void ETSChecker::CreateLambdaObjectForFunctionReference(ir::AstNode *refNode, Si return; } + /* signature has been converted through BpxPrimitives, we need to call the original one */ + auto *trueSignature = signature->Function()->Signature(); + // Create the class scope for the synthetic lambda class node auto classCtx = varbinder::LexicalScope(VarBinder()); auto *classScope = classCtx.GetScope(); - bool isStaticReference = signature->HasSignatureFlag(SignatureFlags::STATIC); + bool isStaticReference = trueSignature->HasSignatureFlag(SignatureFlags::STATIC); // Create the synthetic field where we will store the instance object which we are trying to obtain the function // reference through, if the referenced function is static, we won't need to store the instance object @@ -2229,15 +2276,17 @@ void ETSChecker::CreateLambdaObjectForFunctionReference(ir::AstNode *refNode, Si // Create the template for the synthetic invoke function which will propagate the function call to the saved // instance's referenced function, or the class static function, if this is a static reference - auto *invokeFunc = CreateLambdaInvokeProto(); + auto *invoke0Func = CreateLambdaInvokeProto(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME); + auto *invokeFunc = CreateLambdaInvokeProto("invoke"); + properties.push_back(invoke0Func); properties.push_back(invokeFunc); // Create the declarations for the synthetic constructor and invoke method CreateLambdaFuncDecl(ctor, classScope->StaticMethodScope()); + CreateLambdaFuncDecl(invoke0Func, classScope->InstanceMethodScope()); CreateLambdaFuncDecl(invokeFunc, classScope->InstanceMethodScope()); // Create the synthetic lambda class node - ArenaVector implements(Allocator()->Adapter()); auto *identNode = Allocator()->New(util::StringView("LambdaObject"), Allocator()); auto *lambdaObject = Allocator()->New(Allocator(), identNode, std::move(properties), @@ -2245,14 +2294,15 @@ void ETSChecker::CreateLambdaObjectForFunctionReference(ir::AstNode *refNode, Si lambdaObject->SetScope(classScope); // Set the parent nodes ctor->SetParent(lambdaObject); + invoke0Func->SetParent(lambdaObject); invokeFunc->SetParent(lambdaObject); classScope->BindNode(lambdaObject); // Build the lambda object in the binder - VarBinder()->AsETSBinder()->BuildLambdaObject(refNode, lambdaObject, signature); + VarBinder()->AsETSBinder()->BuildLambdaObject(refNode, lambdaObject, trueSignature); // Resolve the lambda object - ResolveLambdaObject(lambdaObject, signature, functionalInterface, refNode); + ResolveLambdaObject(lambdaObject, trueSignature, functionalInterface, refNode); } ir::AstNode *ETSChecker::CreateLambdaImplicitField(varbinder::ClassScope *scope, const lexer::SourcePosition &pos) @@ -2340,11 +2390,11 @@ std::tuple ETSChecker::C return {paramCtx.GetScope(), nullptr}; } -ir::MethodDefinition *ETSChecker::CreateLambdaInvokeProto() +ir::MethodDefinition *ETSChecker::CreateLambdaInvokeProto(util::StringView invokeName) { // Create the template for the synthetic 'invoke' method, which will be used when the function type will be // called - auto *name = Allocator()->New("invoke", Allocator()); + auto *name = Allocator()->New(invokeName, Allocator()); auto *paramScope = VarBinder()->Allocator()->New(Allocator(), VarBinder()->GetScope()); auto *scope = VarBinder()->Allocator()->New(Allocator(), paramScope); @@ -2426,13 +2476,14 @@ void ETSChecker::ResolveLambdaObject(ir::ClassDefinition *lambdaObject, Signatur ResolveLambdaObjectCtor(lambdaObject, isStaticReference); // Resolve the invoke function - ResolveLambdaObjectInvoke(lambdaObject, signature); + ResolveLambdaObjectInvoke(lambdaObject, signature, true); + ResolveLambdaObjectInvoke(lambdaObject, signature, false); } void ETSChecker::ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject, bool isStaticReference) { const auto &lambdaBody = lambdaObject->Body(); - auto *ctorFunc = lambdaBody[lambdaBody.size() - 2]->AsMethodDefinition()->Function(); + auto *ctorFunc = lambdaBody[lambdaBody.size() - 3]->AsMethodDefinition()->Function(); ETSObjectType *lambdaObjectType = lambdaObject->TsType()->AsETSObjectType(); varbinder::Variable *fieldVar {}; @@ -2490,41 +2541,70 @@ void ETSChecker::ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject, bool fieldinit->Right()->SetTsType(ctorSignature->Params()[0]->TsType()); } -void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Signature *signatureRef) +static Signature *CreateInvokeSignature(ETSChecker *checker, Signature *signatureRef, ir::ScriptFunction *invokeFunc, + ETSObjectType *lambdaObjectType, bool ifaceOverride) { - const auto &lambdaBody = lambdaObject->Body(); - auto *invokeFunc = lambdaBody[lambdaBody.size() - 1]->AsMethodDefinition()->Function(); - ETSObjectType *lambdaObjectType = lambdaObject->TsType()->AsETSObjectType(); - - // Set the implicit 'this' parameters type to the lambda object - auto *thisVar = invokeFunc->Scope()->ParamScope()->Params().front(); - thisVar->SetTsType(lambdaObjectType); + auto *allocator = checker->Allocator(); // Create the signature for the invoke function type - auto *invokeSignatureInfo = CreateSignatureInfo(); + auto *invokeSignatureInfo = checker->CreateSignatureInfo(); invokeSignatureInfo->restVar = nullptr; // Create the parameters for the invoke function, based on the referenced function's signature - for (auto *it : signatureRef->Params()) { + auto maxParamsNum = checker->GlobalBuiltinFunctionTypeVariadicThreshold(); + auto paramsNum = signatureRef->Params().size(); + if (paramsNum < maxParamsNum || !ifaceOverride) { + for (auto *it : signatureRef->Params()) { + auto paramCtx = varbinder::LexicalScope::Enter( + checker->VarBinder(), invokeFunc->Scope()->ParamScope(), false); + + auto *paramIdent = allocator->New(it->Name(), allocator); + auto *param = allocator->New(paramIdent, nullptr); + auto [_, var] = checker->VarBinder()->AddParamDecl(param); + (void)_; + var->SetTsType(ifaceOverride ? checker->GlobalETSObjectType() : it->TsType()); + paramIdent->SetVariable(var); + invokeFunc->Params().push_back(param); + invokeSignatureInfo->minArgCount++; + invokeSignatureInfo->params.push_back(var->AsLocalVariable()); + } + } else { auto paramCtx = varbinder::LexicalScope::Enter( - VarBinder(), invokeFunc->Scope()->ParamScope(), false); + checker->VarBinder(), invokeFunc->Scope()->ParamScope(), false); - auto *paramIdent = Allocator()->New(it->Name(), Allocator()); - auto *param = Allocator()->New(paramIdent, nullptr); - auto [_, var] = VarBinder()->AddParamDecl(param); + auto *id = checker->AllocNode("p", allocator); + auto *restElement = checker->AllocNode(ir::AstNodeType::REST_ELEMENT, allocator, id); + auto *const param = checker->AllocNode(restElement, nullptr); + auto [_, var] = checker->VarBinder()->AddParamDecl(param); (void)_; - var->SetTsType(it->TsType()); - paramIdent->SetVariable(var); + var->SetTsType(checker->CreateETSArrayType(checker->GlobalETSObjectType())); + param->Ident()->SetVariable(var); invokeFunc->Params().push_back(param); - invokeSignatureInfo->minArgCount++; - invokeSignatureInfo->params.push_back(var->AsLocalVariable()); + invokeSignatureInfo->restVar = var->AsLocalVariable(); } // Create the function type for the constructor - auto *invokeSignature = CreateSignature(invokeSignatureInfo, signatureRef->ReturnType(), invokeFunc); + auto *invokeSignature = checker->CreateSignature( + invokeSignatureInfo, ifaceOverride ? checker->GlobalETSObjectType() : signatureRef->ReturnType(), invokeFunc); invokeSignature->SetOwner(lambdaObjectType); invokeSignature->AddSignatureFlag(checker::SignatureFlags::CALL); + return invokeSignature; +} + +void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Signature *signatureRef, + bool ifaceOverride) +{ + const auto &lambdaBody = lambdaObject->Body(); + auto *invokeFunc = lambdaBody[lambdaBody.size() - (ifaceOverride ? 2 : 1)]->AsMethodDefinition()->Function(); + ETSObjectType *lambdaObjectType = lambdaObject->TsType()->AsETSObjectType(); + + // Set the implicit 'this' parameters type to the lambda object + auto *thisVar = invokeFunc->Scope()->ParamScope()->Params().front(); + thisVar->SetTsType(lambdaObjectType); + + auto *invokeSignature = CreateInvokeSignature(this, signatureRef, invokeFunc, lambdaObjectType, ifaceOverride); + auto *invokeType = CreateETSFunctionType(invokeSignature); invokeFunc->SetSignature(invokeSignature); invokeFunc->Id()->Variable()->SetTsType(invokeType); @@ -2534,7 +2614,8 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Si // Fill out the type information for the body of the invoke function - auto *resolvedLambdaInvokeFunctionBody = ResolveLambdaObjectInvokeFuncBody(lambdaObject, signatureRef); + auto *resolvedLambdaInvokeFunctionBody = + ResolveLambdaObjectInvokeFuncBody(lambdaObject, signatureRef, ifaceOverride); invokeFunc->Body()->AsBlockStatement()->Statements().push_back(resolvedLambdaInvokeFunctionBody); if (resolvedLambdaInvokeFunctionBody->IsExpressionStatement()) { @@ -2542,7 +2623,80 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Si } } -ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambdaObject, Signature *signatureRef) +static ir::Expression *BuildParamExpression(ETSChecker *checker, ir::Identifier *paramIdent, Type *type) +{ + if (type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + auto *boxedType = checker->PrimitiveTypeAsETSBuiltinType(type); + auto *boxedTypeNode = checker->AllocNode(boxedType); + boxedTypeNode->SetTsType(boxedType); + auto *paramAsExpr = checker->AllocNode(paramIdent, boxedTypeNode, false); + paramAsExpr->SetTsType(boxedType); + paramAsExpr->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(type)); + return paramAsExpr; + } + checker::CastingContext ctx(checker->Relation(), paramIdent, paramIdent->TsType(), type, paramIdent->Start(), {}); + auto *const paramCast = checker->Allocator()->New(paramIdent, nullptr, false); + paramCast->SetUncheckedCast(ctx.UncheckedCast()); + paramCast->SetTsType(type); + return paramCast; +} + +static ArenaVector ResolveCallParametersForLambdaFuncBody(ETSChecker *checker, + Signature *signatureRef, + ir::ScriptFunction *invokeFunc, + bool ifaceOverride) +{ + auto *allocator = checker->Allocator(); + ArenaVector callParams(allocator->Adapter()); + + auto maxParamsNum = checker->GlobalBuiltinFunctionTypeVariadicThreshold(); + auto paramsNum = signatureRef->Params().size(); + if (!ifaceOverride) { + for (size_t idx = 0; idx != paramsNum; idx++) { + auto *paramIdent = allocator->New(signatureRef->Params()[idx]->Name(), allocator); + paramIdent->SetVariable(invokeFunc->Params()[idx]->AsETSParameterExpression()->Variable()); + paramIdent->SetTsType(invokeFunc->Params()[idx]->AsETSParameterExpression()->Variable()->TsType()); + callParams.push_back(paramIdent); + } + } else if (paramsNum < maxParamsNum) { + // Then we add the lambda functions parameters to the call + auto nargs = invokeFunc->Params().size(); + for (size_t i = 0; i < nargs; i++) { + auto const *const param = invokeFunc->Params()[i]->AsETSParameterExpression(); + auto *const paramIdent = allocator->New(param->Ident()->Name(), allocator); + paramIdent->SetVariable(param->Variable()); + paramIdent->SetTsType(param->Variable()->TsType()); + callParams.push_back(BuildParamExpression(checker, paramIdent, signatureRef->Params()[i]->TsType())); + } + } else { + ASSERT(invokeFunc->Params().size() == 1); + auto const *const param = invokeFunc->Params()[0]->AsETSParameterExpression(); + auto *const paramIdent = allocator->New(param->Ident()->Name(), allocator); + paramIdent->SetVariable(param->Variable()); + paramIdent->SetTsType(param->Variable()->TsType()); + + for (size_t i = 0; i < paramsNum; i++) { + auto *idx = allocator->New(lexer::Number(static_cast(i))); + auto *arg = allocator->New(paramIdent, idx, ir::MemberExpressionKind::ELEMENT_ACCESS, + true, false); + + auto *type = signatureRef->Params()[i]->TsType(); + if (type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + arg->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(type)); + callParams.push_back(arg); + } else { + auto *const paramCast = allocator->New(arg, nullptr, false); + paramCast->SetTsType(type); + callParams.push_back(paramCast); + } + } + } + + return callParams; +} + +ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambdaObject, Signature *signatureRef, + bool ifaceOverride) { const auto &lambdaBody = lambdaObject->Body(); bool isStaticReference = signatureRef->HasSignatureFlag(SignatureFlags::STATIC); @@ -2574,14 +2728,9 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition callee->SetTsType(signatureRef->OwnerVar()->TsType()); // Create the parameters for the referenced function call - auto *invokeFunc = lambdaBody[lambdaBody.size() - 1]->AsMethodDefinition()->Function(); - ArenaVector callParams(Allocator()->Adapter()); - for (size_t idx = 0; idx != signatureRef->Params().size(); idx++) { - auto *paramIdent = Allocator()->New(signatureRef->Params()[idx]->Name(), Allocator()); - paramIdent->SetVariable(invokeFunc->Params()[idx]->AsETSParameterExpression()->Variable()); - paramIdent->SetTsType(invokeFunc->Params()[idx]->AsETSParameterExpression()->Variable()->TsType()); - callParams.push_back(paramIdent); - } + auto *invokeFunc = lambdaBody[lambdaBody.size() - (ifaceOverride ? 2 : 1)]->AsMethodDefinition()->Function(); + ArenaVector callParams = + ResolveCallParametersForLambdaFuncBody(this, signatureRef, invokeFunc, ifaceOverride); // Create the synthetic call expression to the referenced function auto *resolvedCall = Allocator()->New(callee, std::move(callParams), nullptr, false); @@ -2592,6 +2741,10 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition return Allocator()->New(resolvedCall); } + if (ifaceOverride && resolvedCall->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + resolvedCall->AddBoxingUnboxingFlags(GetBoxingFlag(resolvedCall->TsType())); + } + return Allocator()->New(resolvedCall); } @@ -2893,4 +3046,22 @@ void ETSChecker::EnsureValidCurlyBrace(ir::CallExpression *callExpr) ThrowTypeError({"No matching call signature with trailing lambda"}, callExpr->Start()); } + +ETSObjectType *ETSChecker::GetCachedFunctionlInterface(ir::ETSFunctionType *type) +{ + auto hash = GetHashFromFunctionType(type); + auto it = functionalInterfaceCache_.find(hash); + if (it == functionalInterfaceCache_.cend()) { + return nullptr; + } + return it->second; +} + +void ETSChecker::CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectType *ifaceType) +{ + auto hash = GetHashFromFunctionType(type); + ASSERT(functionalInterfaceCache_.find(hash) == functionalInterfaceCache_.cend()); + functionalInterfaceCache_.emplace(hash, ifaceType); +} + } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/ets/function_helpers.h b/ets2panda/checker/ets/function_helpers.h index 2fa371318630e76ce3d4e8517f1553beae6ce3a5..ed07549bbcc60c750621e49475c24c1e1c002a13 100644 --- a/ets2panda/checker/ets/function_helpers.h +++ b/ets2panda/checker/ets/function_helpers.h @@ -96,7 +96,9 @@ static const Substitution *BuildImplicitSubstitutionForArguments(ETSChecker *che } auto *argType = arg->Check(checker); argType = MaybeBoxedType(checker, argType, arg); - auto *paramType = (ix < signature->MinArgCount()) ? sigInfo->params[ix]->TsType() : sigInfo->restVar->TsType(); + auto *paramType = (ix < signature->MinArgCount()) ? sigInfo->params[ix]->TsType() + : sigInfo->restVar != nullptr ? sigInfo->restVar->TsType() + : nullptr; if (paramType == nullptr) { continue; } @@ -161,7 +163,10 @@ static Signature *MaybeSubstituteTypeParameters(ETSChecker *checker, Signature * const Substitution *substitution = (typeArguments != nullptr) ? BuildExplicitSubstitutionForArguments(checker, signature, typeArguments->Params(), pos, flags) - : BuildImplicitSubstitutionForArguments(checker, signature, arguments); + : (signature->GetSignatureInfo()->params.empty() + ? nullptr + : BuildImplicitSubstitutionForArguments(checker, signature, arguments)); + return (substitution == nullptr) ? nullptr : signature->Substitute(checker->Relation(), substitution); } @@ -260,4 +265,4 @@ static varbinder::Scope *NodeScope(ir::AstNode *ast) } // namespace panda::es2panda::checker -#endif \ No newline at end of file +#endif diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 41e52fafab41dfa69f6e896b7839b31b51e0f803..46f52f19bd77b88364e92ef3b4f43b9820be4ab7 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -89,7 +89,7 @@ void ETSChecker::CheckTruthinessOfType(ir::Expression *expr) ThrowTypeError("Condition must be of possible condition type", expr->Start()); } - if (unboxedType != nullptr && unboxedType->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { + if (unboxedType->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { FlagExpressionWithUnboxing(type, unboxedType, expr); } expr->SetTsType(unboxedType); @@ -886,7 +886,7 @@ std::tuple ETSChecker::IsResolvedAndValue(const ir::Expression *expr IsNullLikeOrVoidExpression(expr) ? std::make_tuple(true, false) : type->ResolveConditionExpr(); const Type *tsType = expr->TsType(); - if (!tsType->ContainsUndefined() && !tsType->ContainsNull() && !tsType->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { + if (!tsType->ContainsUndefined() && !tsType->ContainsNull() && !type->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { isResolve = true; isValue = true; } @@ -1780,6 +1780,10 @@ Type *ETSChecker::ETSBuiltinTypeAsConditionalType(Type *objectType) return nullptr; } + if (auto *unboxed = ETSBuiltinTypeAsPrimitiveType(objectType); unboxed != nullptr) { + return unboxed; + } + return objectType; } @@ -2294,38 +2298,6 @@ ETSObjectType *ETSChecker::GetRelevantArgumentedTypeFromChild(ETSObjectType *con return GetRelevantArgumentedTypeFromChild(child->SuperType(), target); } -static void TypeToString(std::stringstream &ss, Type *tp) -{ - if (tp->IsETSTypeParameter()) { - ss << tp->AsETSTypeParameter()->GetDeclNode()->Start().index; - ss << "."; - } - if (!tp->IsETSObjectType()) { - tp->ToString(ss); - return; - } - auto *const objType = tp->AsETSObjectType(); - ss << objType->Name(); - - if (!objType->TypeArguments().empty()) { - auto typeArgs = objType->TypeArguments(); - ss << "<"; - for (auto *ta : typeArgs) { - TypeToString(ss, ta); - ss << ";"; - } - ss << ">"; - } - - if (tp->ContainsNull()) { - ss << "|null"; - } - - if (tp->ContainsUndefined()) { - ss << "|undefined"; - } -} - void ETSChecker::EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg) { substitution->emplace(tparam, typeArg); @@ -2336,7 +2308,7 @@ util::StringView ETSChecker::GetHashFromTypeArguments(const ArenaVector std::stringstream ss; for (auto *it : typeArgTypes) { - TypeToString(ss, it); + it->ToString(ss, true); ss << compiler::Signatures::MANGLE_SEPARATOR; } @@ -2348,9 +2320,9 @@ util::StringView ETSChecker::GetHashFromSubstitution(const Substitution *substit std::vector fields; for (auto [k, v] : *substitution) { std::stringstream ss; - TypeToString(ss, k); + k->ToString(ss, true); ss << ":"; - TypeToString(ss, v); + v->ToString(ss, true); fields.push_back(ss.str()); } std::sort(fields.begin(), fields.end()); @@ -2363,6 +2335,29 @@ util::StringView ETSChecker::GetHashFromSubstitution(const Substitution *substit return util::UString(ss.str(), Allocator()).View(); } +util::StringView ETSChecker::GetHashFromFunctionType(ir::ETSFunctionType *type) +{ + std::stringstream ss; + for (auto *p : type->Params()) { + auto *const param = p->AsETSParameterExpression(); + GetTypeFromTypeAnnotation(param->TypeAnnotation())->ToString(ss, true); + ss << ";"; + } + + type->ReturnType()->GetType(this)->ToString(ss, true); + ss << ";"; + + if (type->IsThrowing()) { + ss << "throws;"; + } + + if (type->IsRethrowing()) { + ss << "rethrows;"; + } + + return util::UString(ss.str(), Allocator()).View(); +} + ETSObjectType *ETSChecker::GetOriginalBaseType(Type *const object) { if (object == nullptr || !object->IsETSObjectType()) { @@ -2419,6 +2414,10 @@ void ETSChecker::CheckNumberOfTypeArguments(ETSObjectType *const type, ir::TSTyp return; } + if (typeArgs == nullptr) { + return; + } + size_t minimumTypeArgs = std::count_if(typeParams.begin(), typeParams.end(), [](Type *param) { return param->AsETSTypeParameter()->GetDefaultType() == nullptr; }); @@ -2638,35 +2637,35 @@ std::string GenerateImplicitInstantiateArg(varbinder::LocalVariable *instantiate return implicitInstantiateArgument; } -void ETSChecker::GenerateGetterSetterBody(ETSChecker *checker, ArenaVector &stmts, - ArenaVector ¶ms, ir::ClassProperty *const field, - varbinder::FunctionParamScope *paramScope, bool isSetter) +void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, ArenaVector ¶ms, + ir::ClassProperty *const field, varbinder::FunctionParamScope *paramScope, + bool isSetter) { if (!isSetter) { - stmts.push_back(checker->Allocator()->New(field->Key())); + stmts.push_back(Allocator()->New(field->Key())); return; } - auto *paramIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator()); - paramIdent->SetTsTypeAnnotation(field->TypeAnnotation()->Clone(checker->Allocator())); + auto *paramIdent = field->Key()->AsIdentifier()->Clone(Allocator()); + paramIdent->SetTsTypeAnnotation(field->TypeAnnotation()->Clone(Allocator())); paramIdent->TypeAnnotation()->SetParent(paramIdent); - auto *paramExpression = checker->AllocNode(paramIdent, nullptr); + auto *paramExpression = AllocNode(paramIdent, nullptr); paramExpression->SetRange(paramIdent->Range()); - auto *const paramVar = std::get<2>(paramScope->AddParamDecl(checker->Allocator(), paramExpression)); + auto *const paramVar = std::get<2>(paramScope->AddParamDecl(Allocator(), paramExpression)); paramIdent->SetVariable(paramVar); paramExpression->SetVariable(paramVar); params.push_back(paramExpression); - auto *assignmentExpression = checker->AllocNode( - field->Key(), paramExpression, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + auto *assignmentExpression = + AllocNode(field->Key(), paramExpression, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); assignmentExpression->SetRange({field->Start(), field->End()}); - stmts.push_back(checker->AllocNode(assignmentExpression)); - stmts.push_back(checker->Allocator()->New(nullptr)); + stmts.push_back(AllocNode(assignmentExpression)); + stmts.push_back(Allocator()->New(nullptr)); } ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty *const field, @@ -2683,7 +2682,7 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty ArenaVector params(checker->Allocator()->Adapter()); ArenaVector stmts(checker->Allocator()->Adapter()); - checker->GenerateGetterSetterBody(checker, stmts, params, field, paramScope, isSetter); + checker->GenerateGetterSetterBody(stmts, params, field, paramScope, isSetter); auto *body = checker->AllocNode(checker->Allocator(), std::move(stmts)); auto funcFlags = isSetter ? ir::ScriptFunctionFlags::SETTER : ir::ScriptFunctionFlags::GETTER; @@ -2730,7 +2729,7 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty const Type *ETSChecker::TryGettingFunctionTypeFromInvokeFunction(const Type *type) const { if (type->IsETSObjectType() && type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { - auto const propInvoke = type->AsETSObjectType()->GetProperty(util::StringView("invoke"), + auto const propInvoke = type->AsETSObjectType()->GetProperty(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME, PropertySearchFlags::SEARCH_INSTANCE_METHOD); ASSERT(propInvoke != nullptr); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 8c06deccbc40e0c84799fcc304c753c462a02968..24e9928347a1e731b02868b73d6a0593f164e399 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -285,9 +285,10 @@ void ETSChecker::CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type : type->GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); type->SetTypeArguments(CreateTypeForTypeParameters(typeParams)); type->AddObjectFlag(ETSObjectFlags::RESOLVED_TYPE_PARAMS); + type->AddObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION); } -ETSObjectType *ETSChecker::BuildInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl) +ETSObjectType *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl) { auto *var = interfaceDecl->Id()->Variable(); ASSERT(var); @@ -309,6 +310,14 @@ ETSObjectType *ETSChecker::BuildInterfaceProperties(ir::TSInterfaceDeclaration * GetInterfacesOfInterface(interfaceType); + interfaceType->SetSuperType(GlobalETSObjectType()); + + return interfaceType; +} + +ETSObjectType *ETSChecker::BuildInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl) +{ + auto *interfaceType = BuildBasicInterfaceProperties(interfaceDecl); checker::ScopeContext scopeCtx(this, interfaceDecl->Scope()); auto savedContext = checker::SavedCheckerContext(this, checker::CheckerStatus::IN_INTERFACE, interfaceType); @@ -317,7 +326,7 @@ ETSObjectType *ETSChecker::BuildInterfaceProperties(ir::TSInterfaceDeclaration * return interfaceType; } -ETSObjectType *ETSChecker::BuildClassProperties(ir::ClassDefinition *classDef) +ETSObjectType *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) { if (classDef->IsFinal() && classDef->IsAbstract()) { ThrowTypeError("Cannot use both 'final' and 'abstract' modifiers.", classDef->Start()); @@ -327,7 +336,6 @@ ETSObjectType *ETSChecker::BuildClassProperties(ir::ClassDefinition *classDef) ASSERT(var); const util::StringView &className = classDef->Ident()->Name(); - auto *classScope = classDef->Scope(); checker::ETSObjectType *classType {}; if (var->TsType() == nullptr) { @@ -368,10 +376,17 @@ ETSObjectType *ETSChecker::BuildClassProperties(ir::ClassDefinition *classDef) return classType; } - checker::ScopeContext scopeCtx(this, classScope); + return classType; +} - ResolveDeclaredMembersOfObject(classType); +ETSObjectType *ETSChecker::BuildClassProperties(ir::ClassDefinition *classDef) +{ + auto *classType = BuildBasicClassProperties(classDef); + auto savedContext = checker::SavedCheckerContext(this, checker::CheckerStatus::IN_CLASS, classType); + checker::ScopeContext scopeCtx(this, classDef->Scope()); + + ResolveDeclaredMembersOfObject(classType); return classType; } @@ -1586,7 +1601,8 @@ void ETSChecker::AddElementsToModuleObject(ETSObjectType *moduleObj, const util: Type *ETSChecker::FindLeastUpperBound(Type *source, Type *target) { - ASSERT(source->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT) && target->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT)); + ASSERT(source->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT | TypeFlag::ETS_TYPE_PARAMETER)); + ASSERT(target->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT | TypeFlag::ETS_TYPE_PARAMETER)); // GetCommonClass(GenA, GenB) => LUB(GenA, GenB) auto commonClass = GetCommonClass(source, target); @@ -1695,7 +1711,12 @@ ETSObjectType *ETSChecker::GetTypeargumentedLUB(ETSObjectType *const source, ETS return source; } - ETSObjectType *templateType = source->GetDeclNode()->AsClassDefinition()->TsType()->AsETSObjectType(); + ETSObjectType *templateType; + if (source->GetDeclNode()->IsClassDefinition()) { + templateType = source->GetDeclNode()->AsClassDefinition()->TsType()->AsETSObjectType(); + } else { + templateType = source->GetDeclNode()->AsTSInterfaceDeclaration()->TsType()->AsETSObjectType(); + } auto *lubType = templateType->GetInstantiatedType(hash); diff --git a/ets2panda/checker/types/ets/byteType.h b/ets2panda/checker/types/ets/byteType.h index cd81d91cd3ad250330121d70bbc1c1ab71291f73..3bc9deb36dd38b0e039c69f375ce295f8d674020 100644 --- a/ets2panda/checker/types/ets/byteType.h +++ b/ets2panda/checker/types/ets/byteType.h @@ -37,12 +37,12 @@ public: void Cast(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "byte"; } - void ToAssemblerType([[maybe_unused]] std::stringstream &ss) const override + void ToAssemblerType(std::stringstream &ss) const override { ss << compiler::Signatures::PRIMITIVE_BYTE; } diff --git a/ets2panda/checker/types/ets/charType.h b/ets2panda/checker/types/ets/charType.h index f917156bcf5ac851bc61ddd2a9deee84ed26b184..54641c35d1adf14cf2b36cecb725d1cd928d257d 100644 --- a/ets2panda/checker/types/ets/charType.h +++ b/ets2panda/checker/types/ets/charType.h @@ -37,7 +37,7 @@ public: void Cast(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "char"; } diff --git a/ets2panda/checker/types/ets/doubleType.h b/ets2panda/checker/types/ets/doubleType.h index ddf7cc3e41102344f620e13423eda07d67a6e84e..57579724f2d938e407d4b610d81bbc1f1670c06f 100644 --- a/ets2panda/checker/types/ets/doubleType.h +++ b/ets2panda/checker/types/ets/doubleType.h @@ -37,7 +37,7 @@ public: void Cast(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "double"; } diff --git a/ets2panda/checker/types/ets/etsArrayType.cpp b/ets2panda/checker/types/ets/etsArrayType.cpp index 9b0e9403aad8cc4a0cc7699c4f027367add94ac6..ec422c7e122d602b5d9933e8d8d8b193614fcec7 100644 --- a/ets2panda/checker/types/ets/etsArrayType.cpp +++ b/ets2panda/checker/types/ets/etsArrayType.cpp @@ -21,9 +21,16 @@ #include "checker/types/typeRelation.h" namespace panda::es2panda::checker { -void ETSArrayType::ToString(std::stringstream &ss) const +void ETSArrayType::ToString(std::stringstream &ss, bool precise) const { - element_->ToString(ss); + bool needParens = (element_->IsETSUnionType() || element_->IsETSFunctionType() || element_->IsNullish()); + if (needParens) { + ss << "("; + } + element_->ToString(ss, precise); + if (needParens) { + ss << ")"; + } ss << "[]"; if (IsNullish()) { diff --git a/ets2panda/checker/types/ets/etsArrayType.h b/ets2panda/checker/types/ets/etsArrayType.h index f4f90331b9512aa7c8c929e2e8e97343351801fd..edd0ddde3cc1b5ee5b644d51fa1734b04bb57d03 100644 --- a/ets2panda/checker/types/ets/etsArrayType.h +++ b/ets2panda/checker/types/ets/etsArrayType.h @@ -38,7 +38,7 @@ public: return {false, false}; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; void ToAssemblerTypeWithRank(std::stringstream &ss) const override; void ToDebugInfoType(std::stringstream &ss) const override; diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp index 71738ebf7c2dc0c640b06f6131719ec5cdb720a7..38550b5097f8b59db27275de1d8b2e18a919890b 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp @@ -18,11 +18,11 @@ #include "checker/types/ets/etsAsyncFuncReturnType.h" namespace panda::es2panda::checker { -void ETSAsyncFuncReturnType::ToString(std::stringstream &ss) const +void ETSAsyncFuncReturnType::ToString(std::stringstream &ss, bool precise) const { - promiseType_->ToString(ss); + promiseType_->ToString(ss, precise); ss << " | "; - GetPromiseTypeArg()->ToString(ss); + GetPromiseTypeArg()->ToString(ss, precise); } void ETSAsyncFuncReturnType::Identical(TypeRelation *relation, Type *other) diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h index 339a3b1d1fb36f9f48d27b22f7d6d134ec4624af..07c9ecf6bddbb8c94178daeedd7b1e3f6ffcf549 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h @@ -30,7 +30,7 @@ public: SetAssemblerName(compiler::Signatures::BUILTIN_OBJECT); } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; diff --git a/ets2panda/checker/types/ets/etsBigIntType.h b/ets2panda/checker/types/ets/etsBigIntType.h index befbfb3de9cd9d965fcc3e063ca4b651f7e752d8..a8b4fa3ecc77596201f4d274022b90c89ce9aea5 100644 --- a/ets2panda/checker/types/ets/etsBigIntType.h +++ b/ets2panda/checker/types/ets/etsBigIntType.h @@ -43,7 +43,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << lexer::TokenToString(lexer::TokenType::KEYW_BIGINT); } diff --git a/ets2panda/checker/types/ets/etsBooleanType.h b/ets2panda/checker/types/ets/etsBooleanType.h index 5127daf1fa56668d143014f3d97f68952eac3dae..4a9f175ea84b921e6c0619d505f8a81f74b39d92 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.h +++ b/ets2panda/checker/types/ets/etsBooleanType.h @@ -36,7 +36,7 @@ public: return value_; } - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "boolean"; } diff --git a/ets2panda/checker/types/ets/etsEnumType.cpp b/ets2panda/checker/types/ets/etsEnumType.cpp index 2a779b6a18f7a7ceb2b72012f9e26405c332b9ad..45d4cdce0fd15559ebe2becb0b29a5364f123a85 100644 --- a/ets2panda/checker/types/ets/etsEnumType.cpp +++ b/ets2panda/checker/types/ets/etsEnumType.cpp @@ -87,7 +87,7 @@ void ETSEnumInterface::ToDebugInfoType(std::stringstream &ss) const ToDebugInfoTypeImpl(ss); } -void ETSEnumInterface::ToString(std::stringstream &ss) const +void ETSEnumInterface::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << decl_->Key()->Name(); } diff --git a/ets2panda/checker/types/ets/etsEnumType.h b/ets2panda/checker/types/ets/etsEnumType.h index 2bd8c99d3e2bc35d51ff9ace55572753de6a8cdb..0ccfa56d29af6b23bb2c0d48f7030c901a77a4d3 100644 --- a/ets2panda/checker/types/ets/etsEnumType.h +++ b/ets2panda/checker/types/ets/etsEnumType.h @@ -60,7 +60,7 @@ public: void ToAssemblerType(std::stringstream &ss) const override; void ToDebugInfoType(std::stringstream &ss) const override; - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; [[nodiscard]] const ir::TSEnumDeclaration *GetDecl() const noexcept; diff --git a/ets2panda/checker/types/ets/etsExtensionFuncHelperType.cpp b/ets2panda/checker/types/ets/etsExtensionFuncHelperType.cpp index b737bd39b44a2bd56258300b4b978e9b461de704..687496405eb080f15abc45929e7c006fbb0b5f95 100644 --- a/ets2panda/checker/types/ets/etsExtensionFuncHelperType.cpp +++ b/ets2panda/checker/types/ets/etsExtensionFuncHelperType.cpp @@ -27,11 +27,11 @@ namespace panda::es2panda::checker { in order to figure out a representation for case 3, we need the etsExtensionFuncHelperType */ -void ETSExtensionFuncHelperType::ToString(std::stringstream &ss) const +void ETSExtensionFuncHelperType::ToString(std::stringstream &ss, bool precise) const { - classMethodType_->ToString(ss); + classMethodType_->ToString(ss, precise); ss << " | "; - extensionFunctionType_->ToString(ss); + extensionFunctionType_->ToString(ss, precise); } void ETSExtensionFuncHelperType::AssignmentTarget(TypeRelation *relation, Type *source) diff --git a/ets2panda/checker/types/ets/etsExtensionFuncHelperType.h b/ets2panda/checker/types/ets/etsExtensionFuncHelperType.h index a646bec1436f1f39ebeb5565437e90ccb2e4eec7..8e4b85c913247c57eba4ff8da4518da96a5d76c9 100644 --- a/ets2panda/checker/types/ets/etsExtensionFuncHelperType.h +++ b/ets2panda/checker/types/ets/etsExtensionFuncHelperType.h @@ -38,7 +38,7 @@ public: return extensionFunctionType_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void AssignmentTarget(TypeRelation *relation, Type *source) override; private: diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index a95e78d4d676aa7e15057237e54a14afa5da5893..38b16d18e45145f78602eb60f817deaf71c0dcf1 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -33,9 +33,9 @@ Signature *ETSFunctionType::FirstAbstractSignature() return nullptr; } -void ETSFunctionType::ToString(std::stringstream &ss) const +void ETSFunctionType::ToString(std::stringstream &ss, bool precise) const { - callSignatures_[0]->ToString(ss, nullptr); + callSignatures_[0]->ToString(ss, nullptr, false, precise); } void ETSFunctionType::Identical(TypeRelation *relation, Type *other) @@ -106,7 +106,7 @@ static Signature *ProcessSignatures(TypeRelation *relation, Signature *target, E size_t idx = 0; for (; idx != target->MinArgCount(); idx++) { - if (!relation->IsIdenticalTo(target->Params()[idx]->TsType(), it->Params()[idx]->TsType())) { + if (!relation->IsAssignableTo(target->Params()[idx]->TsType(), it->Params()[idx]->TsType())) { break; } } @@ -116,11 +116,11 @@ static Signature *ProcessSignatures(TypeRelation *relation, Signature *target, E } if (target->RestVar() != nullptr && - !relation->IsIdenticalTo(target->RestVar()->TsType(), it->RestVar()->TsType())) { + !relation->IsAssignableTo(target->RestVar()->TsType(), it->RestVar()->TsType())) { continue; } - if (!relation->IsAssignableTo(target->ReturnType(), it->ReturnType())) { + if (!relation->IsAssignableTo(it->ReturnType(), target->ReturnType())) { continue; } @@ -130,6 +130,27 @@ static Signature *ProcessSignatures(TypeRelation *relation, Signature *target, E return match; } +static ETSObjectType *SubstitutedFunctionalInterfaceForSignature(TypeRelation *relation, Signature *signature, + ETSObjectType *functionalInterface) +{ + auto &interfaceArgs = functionalInterface->TypeArguments(); + auto *checker = relation->GetChecker()->AsETSChecker(); + Substitution *substitution = checker->NewSubstitution(); + size_t i = 0; + for (auto *param : signature->Params()) { + auto *paramType = (param->TsType()->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) + ? checker->PrimitiveTypeAsETSBuiltinType(param->TsType()) + : param->TsType(); + substitution->emplace(interfaceArgs[i++]->AsETSTypeParameter(), paramType); + } + auto *retType = (signature->ReturnType()->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) + ? checker->PrimitiveTypeAsETSBuiltinType(signature->ReturnType()) + : signature->ReturnType(); + substitution->emplace(interfaceArgs[i]->AsETSTypeParameter(), retType); + + return functionalInterface->Substitute(relation, substitution); +} + void ETSFunctionType::AssignmentTarget(TypeRelation *relation, Type *source) { if (!source->IsETSFunctionType() && @@ -150,8 +171,9 @@ void ETSFunctionType::AssignmentTarget(TypeRelation *relation, Type *source) return; } - if (!target->Function()->IsThrowing()) { - if (match->Function()->IsThrowing() || match->Function()->IsRethrowing()) { + if (!(target->Function()->IsThrowing() || target->HasSignatureFlag(SignatureFlags::THROWS))) { + if (match->Function()->IsThrowing() || match->Function()->IsRethrowing() || + match->HasSignatureFlag(SignatureFlags::THROWS) || match->HasSignatureFlag(SignatureFlags::RETHROWS)) { relation->GetChecker()->ThrowTypeError( "Functions that can throw exceptions cannot be assigned to non throwing functions.", relation->GetNode()->Start()); @@ -160,12 +182,15 @@ void ETSFunctionType::AssignmentTarget(TypeRelation *relation, Type *source) ASSERT(relation->GetNode() != nullptr); if (!sourceIsFunctional) { + auto *substitutedFuncInterface = + SubstitutedFunctionalInterfaceForSignature(relation, match, callSignatures_[0]->Owner()); + if (relation->GetNode()->IsArrowFunctionExpression()) { relation->GetChecker()->AsETSChecker()->CreateLambdaObjectForLambdaReference( - relation->GetNode()->AsArrowFunctionExpression(), callSignatures_[0]->Owner()); + relation->GetNode()->AsArrowFunctionExpression(), substitutedFuncInterface); } else { relation->GetChecker()->AsETSChecker()->CreateLambdaObjectForFunctionReference(relation->GetNode(), match, - callSignatures_[0]->Owner()); + substitutedFuncInterface); } } @@ -206,19 +231,20 @@ ETSFunctionType *ETSFunctionType::Substitute(TypeRelation *relation, const Subst return anyChange ? copiedType : this; } -checker::RelationResult ETSFunctionType::CastFunctionParams(TypeRelation *relation, Type *target) +checker::RelationResult ETSFunctionType::CastFunctionParams(TypeRelation *relation, Signature *targetInvokeSig) { - auto *targetType = target->AsETSObjectType(); - auto *body = targetType->GetDeclNode()->AsTSInterfaceDeclaration()->Body(); - auto targetParams = body->AsTSInterfaceBody()->Body()[0]->AsMethodDefinition()->Function()->Params(); - for (size_t i = 0; i < targetType->TypeArguments().size(); i++) { + auto *ourSig = callSignatures_[0]; + auto &ourParams = ourSig->Params(); + auto &theirParams = targetInvokeSig->Params(); + if (ourParams.size() != theirParams.size()) { + return RelationResult::FALSE; + } + for (size_t i = 0; i < theirParams.size(); i++) { relation->Result(RelationResult::FALSE); - callSignatures_[0]->Function()->Params()[i]->TsType()->Cast( - relation, targetParams[i]->AsETSParameterExpression()->Check(relation->GetChecker()->AsETSChecker())); - if (relation->IsTrue()) { - continue; + ourParams[i]->TsType()->Cast(relation, theirParams[i]->TsType()); + if (!relation->IsTrue()) { + return RelationResult::FALSE; } - return RelationResult::FALSE; } return RelationResult::TRUE; } @@ -226,23 +252,37 @@ checker::RelationResult ETSFunctionType::CastFunctionParams(TypeRelation *relati void ETSFunctionType::Cast(TypeRelation *relation, Type *target) { ASSERT(relation->GetNode()->IsArrowFunctionExpression()); + auto *savedNode = relation->GetNode(); + conversion::Forbidden(relation); if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { auto *targetType = target->AsETSObjectType(); - auto *body = targetType->GetDeclNode()->AsTSInterfaceDeclaration()->Body()->AsTSInterfaceBody(); - auto targetParams = body->AsTSInterfaceBody()->Body()[0]->AsMethodDefinition()->Function()->Params(); - if (targetType->HasObjectFlag(ETSObjectFlags::FUNCTIONAL_INTERFACE) && - targetParams.size() == callSignatures_[0]->Function()->Params().size()) { - relation->Result(CastFunctionParams(relation, target)); + if (targetType->HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { + auto *targetInvokeVar = targetType->GetProperty(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME, + PropertySearchFlags::SEARCH_INSTANCE_METHOD); + if (targetInvokeVar == nullptr || !targetInvokeVar->TsType()->IsETSFunctionType()) { + return; + } + auto *targetInvokeSig = targetInvokeVar->TsType()->AsETSFunctionType()->CallSignatures()[0]; + relation->Result(CastFunctionParams(relation, targetInvokeSig)); + auto *targetReturnType = targetInvokeSig->ReturnType(); + callSignatures_[0]->ReturnType()->Cast(relation, targetReturnType); } - relation->Result(RelationResult::FALSE); - auto targetReturnType = body->Body()[0]->AsMethodDefinition()->Function()->ReturnTypeAnnotation(); - callSignatures_[0]->ReturnType()->Cast(relation, targetReturnType->TsType()); if (relation->IsTrue()) { relation->GetChecker()->AsETSChecker()->CreateLambdaObjectForLambdaReference( relation->GetNode()->AsArrowFunctionExpression(), targetType->AsETSObjectType()); + relation->SetNode(savedNode); return; } } - conversion::Forbidden(relation); +} + +ETSFunctionType *ETSFunctionType::BoxPrimitives(ETSChecker *checker) +{ + auto *allocator = checker->Allocator(); + auto *ret = allocator->New(name_, allocator); + for (auto *sig : callSignatures_) { + ret->AddCallSignature(sig->BoxPrimitives(checker)); + } + return ret; } } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsFunctionType.h b/ets2panda/checker/types/ets/etsFunctionType.h index 2d79f87d3c7e77db11b32a4b48956b62ba212c36..c275b1b7300db574d3a85f5fedf8b0ed165f4d44 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.h +++ b/ets2panda/checker/types/ets/etsFunctionType.h @@ -112,14 +112,15 @@ public: } Signature *FirstAbstractSignature(); - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; ETSFunctionType *Substitute(TypeRelation *relation, const Substitution *substitution) override; void Cast(TypeRelation *relation, Type *target) override; - checker::RelationResult CastFunctionParams(TypeRelation *relation, Type *target); + checker::RelationResult CastFunctionParams(TypeRelation *relation, Signature *targetInvokeSig); + ETSFunctionType *BoxPrimitives(ETSChecker *checker); private: ArenaVector callSignatures_; diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 5891c506419167fd360e3a1807ec48e13b105b0c..28e219d850b37e14320776c3cc121aef2315bc4e 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -281,14 +281,16 @@ ArenaMap ETSObjectType::Coll return propMap; } -void ETSObjectType::ToString(std::stringstream &ss) const +void ETSObjectType::ToString(std::stringstream &ss, bool precise) const { if (HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { if (IsNullish() && this != GetConstOriginalBaseType() && !name_.Is("NullType") && !IsETSNullLike() && !name_.Empty()) { ss << lexer::TokenToString(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); } - GetFunctionalInterfaceInvokeType()->ToString(ss); + GetFunctionalInterfaceInvokeType()->ToString(ss, precise); + } else if (precise) { + ss << assemblerName_; // NOTE(gogabr): need full qualified name } else { ss << name_; } @@ -296,7 +298,7 @@ void ETSObjectType::ToString(std::stringstream &ss) const if (!typeArguments_.empty()) { ss << compiler::Signatures::GENERIC_BEGIN; for (auto arg = typeArguments_.cbegin(); arg != typeArguments_.cend(); ++arg) { - (*arg)->ToString(ss); + (*arg)->ToString(ss, precise); if (next(arg) != typeArguments_.cend()) { ss << lexer::TokenToString(lexer::TokenType::PUNCTUATOR_COMMA); @@ -321,7 +323,7 @@ void ETSObjectType::ToString(std::stringstream &ss) const } } -void ETSObjectType::IdenticalUptoNullability(TypeRelation *relation, Type *other) +void ETSObjectType::IdenticalUptoNullabilityAndTypeArguments(TypeRelation *relation, Type *other) { relation->Result(false); if (!other->IsETSObjectType() || !CheckIdenticalFlags(other->AsETSObjectType()->ObjectFlags())) { @@ -339,57 +341,55 @@ void ETSObjectType::IdenticalUptoNullability(TypeRelation *relation, Type *other return; } - auto const otherTypeArguments = other->AsETSObjectType()->TypeArguments(); + if (IsNullish()) { + relation->Result(true); + return; + } - if (HasTypeFlag(TypeFlag::GENERIC) || IsNullish()) { - if (!HasTypeFlag(TypeFlag::GENERIC)) { - relation->Result(true); - return; - } - if (typeArguments_.empty() != otherTypeArguments.empty()) { - return; - } + auto const sourceTypeArguments = other->AsETSObjectType()->TypeArguments(); + if (typeArguments_.empty() != sourceTypeArguments.empty()) { + return; + } - auto const argsNumber = typeArguments_.size(); - ASSERT(argsNumber == otherTypeArguments.size()); + relation->Result(true); +} - for (size_t idx = 0U; idx < argsNumber; ++idx) { - if (typeArguments_[idx]->IsWildcardType() || otherTypeArguments[idx]->IsWildcardType()) { - continue; - } +void ETSObjectType::IdenticalUptoNullability(TypeRelation *relation, Type *other) +{ + IdenticalUptoNullabilityAndTypeArguments(relation, other); - // checking the nullishness of type args before getting their original base types - // because most probably GetOriginalBaseType will return the non-nullish version of the type - if (!typeArguments_[idx]->IsNullish() && otherTypeArguments[idx]->IsNullish()) { - return; - } + if (!relation->IsTrue() || !HasTypeFlag(TypeFlag::GENERIC)) { + return; + } + + auto const otherTypeArguments = other->AsETSObjectType()->TypeArguments(); - const auto getOriginalBaseTypeOrType = [&relation](Type *const originalType) { - auto *const baseType = relation->GetChecker()->AsETSChecker()->GetOriginalBaseType(originalType); - return baseType == nullptr ? originalType : baseType; - }; + auto const argsNumber = typeArguments_.size(); + ASSERT(argsNumber == otherTypeArguments.size()); - auto *const typeArgType = getOriginalBaseTypeOrType(typeArguments_[idx]); - auto *const otherTypeArgType = getOriginalBaseTypeOrType(otherTypeArguments[idx]); + for (size_t idx = 0U; idx < argsNumber; ++idx) { + if (typeArguments_[idx]->IsWildcardType() || otherTypeArguments[idx]->IsWildcardType()) { + continue; + } - typeArgType->Identical(relation, otherTypeArgType); - if (!relation->IsTrue()) { - return; - } + // checking the nullishness of type args before getting their original base types + // because most probably GetOriginalBaseType will return the non-nullish version of the type + if ((!typeArguments_[idx]->IsNullish() && otherTypeArguments[idx]->IsNullish()) || + (typeArguments_[idx]->IsNullish() && !otherTypeArguments[idx]->IsNullish())) { + relation->Result(false); + return; } - } else { - if (HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { - auto getInvokeSignature = [](const ETSObjectType *type) { - auto const propInvoke = - type->GetProperty(util::StringView("invoke"), PropertySearchFlags::SEARCH_INSTANCE_METHOD); - ASSERT(propInvoke != nullptr); - return propInvoke->TsType()->AsETSFunctionType()->CallSignatures()[0]; - }; - auto *const thisInvokeSignature = getInvokeSignature(this); - auto *const otherInvokeSignature = getInvokeSignature(other->AsETSObjectType()); + const auto getOriginalBaseTypeOrType = [&relation](Type *const originalType) { + auto *const baseType = relation->GetChecker()->AsETSChecker()->GetOriginalBaseType(originalType); + return baseType == nullptr ? originalType : baseType; + }; + + auto *const typeArgType = getOriginalBaseTypeOrType(typeArguments_[idx]); + auto *const otherTypeArgType = getOriginalBaseTypeOrType(otherTypeArguments[idx]); - relation->IsIdenticalTo(thisInvokeSignature, otherInvokeSignature); + typeArgType->Identical(relation, otherTypeArgType); + if (!relation->IsTrue()) { return; } } @@ -445,8 +445,12 @@ void ETSObjectType::AssignmentTarget(TypeRelation *const relation, Type *source) if (HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { EnsurePropertiesInstantiated(); - auto found = properties_[static_cast(PropertyType::INSTANCE_METHOD)].find("invoke"); + auto found = properties_[static_cast(PropertyType::INSTANCE_METHOD)].find( + FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME); ASSERT(found != properties_[static_cast(PropertyType::INSTANCE_METHOD)].end()); + if (source->IsETSFunctionType()) { + source = source->AsETSFunctionType()->BoxPrimitives(relation->GetChecker()->AsETSChecker()); + } relation->IsAssignableTo(source, found->second->TsType()); return; } @@ -474,10 +478,14 @@ bool ETSObjectType::CastWideningNarrowing(TypeRelation *const relation, Type *co bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const target) { - if (this->IsNullish()) { + if (!target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | + TypeFlag::FLOAT | TypeFlag::DOUBLE | TypeFlag::ETS_BOOLEAN)) { return false; } - + IdenticalUptoNullability(relation, target); + if (relation->IsTrue()) { + return true; + } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_BYTE)) { if (target->HasTypeFlag(TypeFlag::BYTE)) { conversion::Unboxing(relation, this); @@ -493,63 +501,42 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const return true; } } - TypeFlag unboxFlags = TypeFlag::NONE; - TypeFlag wideningFlags = TypeFlag::NONE; - TypeFlag narrowingFlags = TypeFlag::NONE; - if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT)) { - unboxFlags = TypeFlag::SHORT; - wideningFlags = TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE; - narrowingFlags = TypeFlag::BYTE | TypeFlag::CHAR; - if (CastWideningNarrowing(relation, target, unboxFlags, wideningFlags, narrowingFlags)) { - return true; - } + if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT) && + CastWideningNarrowing(relation, target, TypeFlag::SHORT, + TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE, + TypeFlag::BYTE | TypeFlag::CHAR)) { + return true; } - if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { - unboxFlags = TypeFlag::CHAR; - wideningFlags = TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE; - narrowingFlags = TypeFlag::BYTE | TypeFlag::SHORT; - if (CastWideningNarrowing(relation, target, unboxFlags, wideningFlags, narrowingFlags)) { - return true; - } + if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR) && + CastWideningNarrowing(relation, target, TypeFlag::CHAR, + TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE, + TypeFlag::BYTE | TypeFlag::SHORT)) { + return true; } - if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_INT)) { - unboxFlags = TypeFlag::INT; - wideningFlags = TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE; - narrowingFlags = TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR; - if (CastWideningNarrowing(relation, target, unboxFlags, wideningFlags, narrowingFlags)) { - return true; - } + if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_INT) && + CastWideningNarrowing(relation, target, TypeFlag::INT, TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE, + TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR)) { + return true; } - if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG)) { - unboxFlags = TypeFlag::LONG; - wideningFlags = TypeFlag::FLOAT | TypeFlag::DOUBLE; - narrowingFlags = TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT; - if (CastWideningNarrowing(relation, target, unboxFlags, wideningFlags, narrowingFlags)) { - return true; - } + if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG) && + CastWideningNarrowing(relation, target, TypeFlag::LONG, TypeFlag::FLOAT | TypeFlag::DOUBLE, + TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT)) { + return true; } - if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT)) { - unboxFlags = TypeFlag::FLOAT; - wideningFlags = TypeFlag::DOUBLE; - narrowingFlags = TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG; - if (CastWideningNarrowing(relation, target, unboxFlags, wideningFlags, narrowingFlags)) { - return true; - } + if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT) && + CastWideningNarrowing(relation, target, TypeFlag::FLOAT, TypeFlag::DOUBLE, + TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG)) { + return true; } - if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE)) { - unboxFlags = TypeFlag::DOUBLE; - wideningFlags = TypeFlag::NONE; - narrowingFlags = + if (auto narrowingFlags = TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT; - if (CastWideningNarrowing(relation, target, unboxFlags, wideningFlags, narrowingFlags)) { - return true; - } + this->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE) && + CastWideningNarrowing(relation, target, TypeFlag::DOUBLE, TypeFlag::NONE, narrowingFlags)) { + return true; } - if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN)) { - if (target->HasTypeFlag(TypeFlag::ETS_BOOLEAN)) { - conversion::Unboxing(relation, this); - return true; - } + if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN) && target->HasTypeFlag(TypeFlag::ETS_BOOLEAN)) { + conversion::Unboxing(relation, this); + return true; } if (this->HasObjectFlag(ETSObjectFlags::UNBOXABLE_TYPE)) { if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { @@ -649,23 +636,31 @@ bool ETSObjectType::DefaultObjectTypeChecks(const ETSChecker *const etsChecker, return true; } - IdenticalUptoNullability(relation, source); + IdenticalUptoNullabilityAndTypeArguments(relation, source); + if (relation->IsTrue() && HasTypeFlag(TypeFlag::GENERIC)) { + IsGenericSupertypeOf(relation, source); + } return relation->IsTrue(); } +static void IsSupertypeOfUnion(TypeRelation *relation, ETSObjectType *self, ETSUnionType *unionType) +{ + bool res = std::all_of(unionType->ConstituentTypes().begin(), unionType->ConstituentTypes().end(), + [self, relation](Type *ct) { + relation->Result(false); + self->IsSupertypeOf(relation, ct); + return relation->IsTrue(); + }); + relation->Result(res); +} + void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) { relation->Result(false); auto *const etsChecker = relation->GetChecker()->AsETSChecker(); if (source->IsETSUnionType()) { - bool res = std::all_of(source->AsETSUnionType()->ConstituentTypes().begin(), - source->AsETSUnionType()->ConstituentTypes().end(), [this, relation](Type *ct) { - relation->Result(false); - IsSupertypeOf(relation, ct); - return relation->IsTrue(); - }); - relation->Result(res); + IsSupertypeOfUnion(relation, this, source->AsETSUnionType()); return; } @@ -689,6 +684,51 @@ void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) } } +void ETSObjectType::IsGenericSupertypeOf(TypeRelation *relation, Type *source) +{ + ASSERT(HasTypeFlag(TypeFlag::GENERIC)); + + auto *sourceType = source->AsETSObjectType(); + auto const sourceTypeArguments = sourceType->TypeArguments(); + ASSERT(typeArguments_.size() == sourceTypeArguments.size()); + + ASSERT(declNode_ == sourceType->GetDeclNode()); + + auto *typeParamsDecl = GetTypeParams(); + ASSERT(typeParamsDecl != nullptr || typeArguments_.empty()); + + if (typeParamsDecl == nullptr) { + return; + } + + auto &typeParams = typeParamsDecl->Params(); + ASSERT(typeParams.size() == typeArguments_.size()); + + for (size_t idx = 0; idx < typeArguments_.size(); idx++) { + auto *typeArg = typeArguments_[idx]; + auto *sourceTypeArg = sourceTypeArguments[idx]; + auto *typeParam = typeParams[idx]; + + relation->Result(false); + + if (!(typeArg->IsWildcardType() || sourceTypeArg->IsWildcardType())) { + if (typeParam->IsOut()) { + typeArg->IsSupertypeOf(relation, sourceTypeArg); + } else if (typeParam->IsIn()) { + sourceTypeArg->IsSupertypeOf(relation, typeArg); + } else { + typeArg->Identical(relation, sourceTypeArg); + } + + if (!relation->IsTrue()) { + return; + } + } + } + + relation->Result(true); +} + Type *ETSObjectType::AsSuper(Checker *checker, varbinder::Variable *sourceVar) { if (sourceVar == nullptr) { @@ -845,7 +885,7 @@ void ETSObjectType::SetCopiedTypeProperties(TypeRelation *const relation, ETSObj copiedType->substitution_ = substitution; } -Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution) +ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution, bool cache) { if (substitution == nullptr || substitution->empty()) { return this; @@ -864,8 +904,10 @@ Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *subs } const util::StringView hash = checker->GetHashFromSubstitution(substitution); - if (auto *inst = GetInstantiatedType(hash); inst != nullptr) { - return inst; + if (cache) { + if (auto *inst = GetInstantiatedType(hash); inst != nullptr) { + return inst; + } } if (!relation->TypeInstantiationPossible(base) || IsETSNullLike()) { @@ -875,7 +917,10 @@ Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *subs auto *const copiedType = checker->CreateNewETSObjectType(name_, declNode_, flags_); SetCopiedTypeProperties(relation, copiedType, newTypeArgs, substitution); - GetInstantiationMap().try_emplace(hash, copiedType); + + if (cache) { + GetInstantiationMap().try_emplace(hash, copiedType); + } if (superType_ != nullptr) { copiedType->SetSuperType(superType_->Substitute(relation, substitution)->AsETSObjectType()); @@ -890,6 +935,11 @@ Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *subs return copiedType; } +ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution) +{ + return Substitute(relation, substitution, true); +} + void ETSObjectType::InstantiateProperties() const { if (baseType_ == nullptr || baseType_ == this) { diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index c59e37eb679af296ad1c42556dfef7ddd35f646d..b54010b006e47c53985afcc3587dbfc67125310a 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -112,6 +112,9 @@ enum class PropertyType { COUNT, }; +/* Invoke method name in functional interfaces */ +constexpr char const *FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME = "invoke0"; + class ETSObjectType : public Type { public: using PropertyMap = ArenaUnorderedMap; @@ -392,7 +395,7 @@ public: ETSFunctionType *GetFunctionalInterfaceInvokeType() const { ASSERT(HasObjectFlag(ETSObjectFlags::FUNCTIONAL)); - auto *invoke = GetOwnProperty("invoke"); + auto *invoke = GetOwnProperty(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME); ASSERT(invoke && invoke->TsType() && invoke->TsType()->IsETSFunctionType()); return invoke->TsType()->AsETSFunctionType(); } @@ -414,17 +417,11 @@ public: varbinder::Scope *GetTypeArgumentScope() const { - if (HasObjectFlag(ETSObjectFlags::ENUM) || !HasTypeFlag(TypeFlag::GENERIC)) { + auto *typeParams = GetTypeParams(); + if (typeParams == nullptr) { return nullptr; } - - if (HasObjectFlag(ETSObjectFlags::CLASS)) { - ASSERT(declNode_->IsClassDefinition() && declNode_->AsClassDefinition()->TypeParams()); - return declNode_->AsClassDefinition()->TypeParams()->Scope(); - } - - ASSERT(declNode_->IsTSInterfaceDeclaration() && declNode_->AsTSInterfaceDeclaration()->TypeParams()); - return declNode_->AsTSInterfaceDeclaration()->TypeParams()->Scope(); + return typeParams->Scope(); } InstantiationMap &GetInstantiationMap() @@ -471,7 +468,7 @@ public: bool CheckIdenticalVariable(varbinder::Variable *otherVar) const; void Iterate(const PropertyTraverser &cb) const; - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; @@ -479,7 +476,8 @@ public: bool SubstituteTypeArgs(TypeRelation *relation, ArenaVector &newTypeArgs, const Substitution *substitution); void SetCopiedTypeProperties(TypeRelation *relation, ETSObjectType *copiedType, ArenaVector &newTypeArgs, const Substitution *substitution); - Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; + ETSObjectType *Substitute(TypeRelation *relation, const Substitution *substitution) override; + ETSObjectType *Substitute(TypeRelation *relation, const Substitution *substitution, bool cache); void Cast(TypeRelation *relation, Type *target) override; bool CastNumericObject(TypeRelation *relation, Type *target); bool DefaultObjectTypeChecks(const ETSChecker *etsChecker, TypeRelation *relation, Type *source); @@ -549,6 +547,23 @@ private: void IdenticalUptoNullability(TypeRelation *relation, Type *other); bool CastWideningNarrowing(TypeRelation *relation, Type *target, TypeFlag unboxFlags, TypeFlag wideningFlags, TypeFlag narrowingFlags); + void IdenticalUptoNullabilityAndTypeArguments(TypeRelation *relation, Type *other); + void IsGenericSupertypeOf(TypeRelation *relation, Type *source); + + ir::TSTypeParameterDeclaration *GetTypeParams() const + { + if (HasObjectFlag(ETSObjectFlags::ENUM) || !HasTypeFlag(TypeFlag::GENERIC)) { + return nullptr; + } + + if (HasObjectFlag(ETSObjectFlags::CLASS)) { + ASSERT(declNode_->IsClassDefinition() && declNode_->AsClassDefinition()->TypeParams()); + return declNode_->AsClassDefinition()->TypeParams(); + } + + ASSERT(declNode_->IsTSInterfaceDeclaration() && declNode_->AsTSInterfaceDeclaration()->TypeParams()); + return declNode_->AsTSInterfaceDeclaration()->TypeParams(); + } ArenaAllocator *allocator_; util::StringView name_; diff --git a/ets2panda/checker/types/ets/etsStringType.h b/ets2panda/checker/types/ets/etsStringType.h index afc3c2dd9f195b96c20f502cc49e7aea94894c18..8b96db319e315fabe4d34a751764ca4d6780d753 100644 --- a/ets2panda/checker/types/ets/etsStringType.h +++ b/ets2panda/checker/types/ets/etsStringType.h @@ -43,12 +43,12 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << lexer::TokenToString(lexer::TokenType::KEYW_STRING); } - void ToAssemblerType([[maybe_unused]] std::stringstream &ss) const override + void ToAssemblerType(std::stringstream &ss) const override { ss << compiler::Signatures::BUILTIN_STRING; } diff --git a/ets2panda/checker/types/ets/etsTupleType.cpp b/ets2panda/checker/types/ets/etsTupleType.cpp index 1f79e6f99724de0d5f1c2820f9543ee17b0e1085..2eea1c4084deb2c23262ec2ea462bca7b14d4beb 100644 --- a/ets2panda/checker/types/ets/etsTupleType.cpp +++ b/ets2panda/checker/types/ets/etsTupleType.cpp @@ -20,12 +20,12 @@ #include "ir/ets/etsTuple.h" namespace panda::es2panda::checker { -void ETSTupleType::ToString(std::stringstream &ss) const +void ETSTupleType::ToString(std::stringstream &ss, bool precise) const { ss << "["; for (auto it = typeList_.begin(); it != typeList_.end(); it++) { - (*it)->ToString(ss); + (*it)->ToString(ss, precise); if (std::next(it) != typeList_.end()) { ss << ", "; @@ -34,7 +34,7 @@ void ETSTupleType::ToString(std::stringstream &ss) const if (spreadType_ != nullptr) { ss << ", ..."; - spreadType_->ToString(ss); + spreadType_->ToString(ss, precise); ss << "[]"; } diff --git a/ets2panda/checker/types/ets/etsTupleType.h b/ets2panda/checker/types/ets/etsTupleType.h index 249dbe58cfb3991dfd171a6c4a632c3d61f7946d..ac3bc3ff7949a615dff26058d46ea180788e8e32 100644 --- a/ets2panda/checker/types/ets/etsTupleType.h +++ b/ets2panda/checker/types/ets/etsTupleType.h @@ -80,7 +80,7 @@ public: [[nodiscard]] Type *GetTypeAtIndex(int32_t index) const; - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ets/etsTypeParameter.cpp b/ets2panda/checker/types/ets/etsTypeParameter.cpp index 302f9ce42f07b11e4d28b92ba3813ebca9ab2544..3c1f5b76c9458da6a58eb72d74d4bae294bca91a 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsTypeParameter.cpp @@ -20,8 +20,13 @@ #include "checker/ets/conversion.h" namespace panda::es2panda::checker { -void ETSTypeParameter::ToString(std::stringstream &ss) const + +void ETSTypeParameter::ToString(std::stringstream &ss, bool precise) const { + // Need source file name to avoid clashes + if (precise) { + ss << declNode_->Range().start.index << "." << declNode_->Range().start.line << "."; + } ss << declNode_->Name()->Name(); if (IsNullish()) { diff --git a/ets2panda/checker/types/ets/etsTypeParameter.h b/ets2panda/checker/types/ets/etsTypeParameter.h index 63dabb1358eb560a44e56b955f5b8b66028ecff8..f32f0305db571acec465052aa4120bb74c423f7e 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.h +++ b/ets2panda/checker/types/ets/etsTypeParameter.h @@ -61,7 +61,7 @@ public: return constraint_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index b23981aed59051ab16f3c0313bcc6b9101fdcd90..7f68b971ade1125d3432cc7e7b8260157c1372d7 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -22,10 +22,10 @@ #include "ir/astNode.h" namespace panda::es2panda::checker { -void ETSUnionType::ToString(std::stringstream &ss) const +void ETSUnionType::ToString(std::stringstream &ss, bool precise) const { for (auto it = constituentTypes_.begin(); it != constituentTypes_.end(); it++) { - (*it)->ToString(ss); + (*it)->ToString(ss, precise); if (std::next(it) != constituentTypes_.end()) { ss << "|"; } diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index 216c2630c2289fd3b71898320fbf8e60904d083d..19336608aa1991995246ac535912f7fdac4bc4c4 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -32,7 +32,7 @@ public: return constituentTypes_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; void ToDebugInfoType(std::stringstream &ss) const override; void Identical(TypeRelation *relation, Type *other) override; diff --git a/ets2panda/checker/types/ets/etsVoidType.h b/ets2panda/checker/types/ets/etsVoidType.h index ab280f7e2d669cbe6b4c9e2ff96b5a32e7828c63..e6658fc53f0db8ae73440c5c0d99cdbfe986ab6e 100644 --- a/ets2panda/checker/types/ets/etsVoidType.h +++ b/ets2panda/checker/types/ets/etsVoidType.h @@ -27,7 +27,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "void"; } diff --git a/ets2panda/checker/types/ets/floatType.h b/ets2panda/checker/types/ets/floatType.h index 68da05d2d0d860f364b4cd27373bbc2b31f13489..6c9b92c1c809707acc1b81f72d5c5ab56dc95145 100644 --- a/ets2panda/checker/types/ets/floatType.h +++ b/ets2panda/checker/types/ets/floatType.h @@ -37,7 +37,7 @@ public: void Cast(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "float"; } diff --git a/ets2panda/checker/types/ets/intType.h b/ets2panda/checker/types/ets/intType.h index 2e9734ccc7560d47e08498d6195d39d3d0fad5f0..fab974a6f0192cdc2223b6b18ebaaf30c70aa628 100644 --- a/ets2panda/checker/types/ets/intType.h +++ b/ets2panda/checker/types/ets/intType.h @@ -37,7 +37,7 @@ public: void Cast(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "int"; } diff --git a/ets2panda/checker/types/ets/longType.h b/ets2panda/checker/types/ets/longType.h index e2887d5374200ef53bd5bed45c731a889bad27df..85ee2db7d372550e1dd606492b49e4d319b7bbdd 100644 --- a/ets2panda/checker/types/ets/longType.h +++ b/ets2panda/checker/types/ets/longType.h @@ -37,7 +37,7 @@ public: void Cast(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "long"; } diff --git a/ets2panda/checker/types/ets/shortType.h b/ets2panda/checker/types/ets/shortType.h index 85764fff8368b50c13502fd89826f17bc27afa42..7d0788b4bbae52eecba3e3dbf92aec088e85d244 100644 --- a/ets2panda/checker/types/ets/shortType.h +++ b/ets2panda/checker/types/ets/shortType.h @@ -37,7 +37,7 @@ public: void Cast(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void ToString(std::stringstream &ss) const override + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { ss << "short"; } diff --git a/ets2panda/checker/types/ets/wildcardType.cpp b/ets2panda/checker/types/ets/wildcardType.cpp index aab9ae80b4bb640f13301f32e514d0ce03a64363..7b99a7b06f2d4b82704665042ef99eea52ef851c 100644 --- a/ets2panda/checker/types/ets/wildcardType.cpp +++ b/ets2panda/checker/types/ets/wildcardType.cpp @@ -16,7 +16,7 @@ #include "wildcardType.h" namespace panda::es2panda::checker { -void WildcardType::ToString(std::stringstream &ss) const +void WildcardType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "wildcard"; } diff --git a/ets2panda/checker/types/ets/wildcardType.h b/ets2panda/checker/types/ets/wildcardType.h index 9db1b04df9994ae3cda0054eafb0d581e9b8f9c9..feb18636ec67a10f19e6c309bae7d62c02999be3 100644 --- a/ets2panda/checker/types/ets/wildcardType.h +++ b/ets2panda/checker/types/ets/wildcardType.h @@ -23,7 +23,7 @@ class WildcardType : public Type { public: WildcardType() : Type(TypeFlag::WILDCARD) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index 27115ca55964d3b87dbe05ed8f7ee85ea9c57e63..169afad7a8913ecd6d5c1945808307a42a79b3e6 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -158,6 +158,18 @@ GlobalTypesHolder::GlobalTypesHolder(ArenaAllocator *allocator) : builtinNameMap builtinNameMappings_.emplace("RegExp", GlobalTypeId::ETS_REGEXP_BUILTIN); builtinNameMappings_.emplace("Set", GlobalTypeId::ETS_SET_BUILTIN); + // ETS functional types + for (size_t id = static_cast(GlobalTypeId::ETS_FUNCTION0_CLASS), nargs = 0; + id < static_cast(GlobalTypeId::ETS_FUNCTIONN_CLASS); id++, nargs++) { + std::stringstream ss; + ss << "Function"; + ss << nargs; + + builtinNameMappings_.emplace(util::UString(ss.str(), allocator).View(), static_cast(id)); + } + + builtinNameMappings_.emplace("FunctionN", GlobalTypeId::ETS_FUNCTIONN_CLASS); + // ETS interop js specific types builtinNameMappings_.emplace("JSRuntime", GlobalTypeId::ETS_INTEROP_JSRUNTIME_BUILTIN); builtinNameMappings_.emplace("JSValue", GlobalTypeId::ETS_INTEROP_JSVALUE_BUILTIN); @@ -613,6 +625,20 @@ Type *GlobalTypesHolder::GlobalBuiltinNeverType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_NEVER_BUILTIN)); } +size_t GlobalTypesHolder::VariadicFunctionTypeThreshold() +{ + return static_cast(GlobalTypeId::ETS_FUNCTIONN_CLASS) - + static_cast(GlobalTypeId::ETS_FUNCTION0_CLASS); +} + +Type *GlobalTypesHolder::GlobalFunctionBuiltinType(size_t nargs) +{ + if (nargs >= VariadicFunctionTypeThreshold()) { + return globalTypes_.at(static_cast(GlobalTypeId::ETS_FUNCTIONN_CLASS)); + } + return globalTypes_.at(static_cast(GlobalTypeId::ETS_FUNCTION0_CLASS) + nargs); +} + void GlobalTypesHolder::InitializeBuiltin(const util::StringView name, Type *type) { const auto typeId = builtinNameMappings_.find(name); diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index c79d375a2512aff489471fa4b5f8d7435c8e0535..3f3fb0746558b7986f34d9e0c4f09cf244b5d368 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -112,6 +112,25 @@ enum class GlobalTypeId { ETS_BIG_INT_BUILTIN, ETS_BIG_INT, + ETS_FUNCTION0_CLASS, + ETS_FUNCTION1_CLASS, + ETS_FUNCTION2_CLASS, + ETS_FUNCTION3_CLASS, + ETS_FUNCTION4_CLASS, + ETS_FUNCTION5_CLASS, + ETS_FUNCTION6_CLASS, + ETS_FUNCTION7_CLASS, + ETS_FUNCTION8_CLASS, + ETS_FUNCTION9_CLASS, + ETS_FUNCTION10_CLASS, + ETS_FUNCTION11_CLASS, + ETS_FUNCTION12_CLASS, + ETS_FUNCTION13_CLASS, + ETS_FUNCTION14_CLASS, + ETS_FUNCTION15_CLASS, + ETS_FUNCTION16_CLASS, + ETS_FUNCTIONN_CLASS, + COUNT, }; @@ -204,6 +223,10 @@ public: Type *GlobalDoubleBoxBuiltinType(); Type *GlobalBuiltinNeverType(); + // Functional types + size_t VariadicFunctionTypeThreshold(); + Type *GlobalFunctionBuiltinType(size_t nargs); + // ETS escompat layer Type *GlobalArrayBuiltinType(); Type *GlobalClassOutOfMemoryErrorBuiltinType(); diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index c9e826acf84026e034c63489ca0a42aa53838a12..01feb8044bcfe7a35b34d05f82e35a2e1090b3e4 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -15,6 +15,7 @@ #include "signature.h" +#include "typeFlag.h" #include "varbinder/scope.h" #include "ir/base/scriptFunction.h" #include "ir/ts/tsTypeParameter.h" @@ -118,12 +119,13 @@ Signature *Signature::Copy(ArenaAllocator *allocator, TypeRelation *relation, Gl return copiedSignature; } -void Signature::ToString(std::stringstream &ss, const varbinder::Variable *variable, bool printAsMethod) const +void Signature::ToString(std::stringstream &ss, const varbinder::Variable *variable, bool printAsMethod, + bool precise) const { if (!signatureInfo_->typeParams.empty()) { ss << "<"; for (auto it = signatureInfo_->typeParams.begin(); it != signatureInfo_->typeParams.end(); ++it) { - (*it)->ToString(ss); + (*it)->ToString(ss, precise); if (std::next(it) != signatureInfo_->typeParams.end()) { ss << ", "; } @@ -142,7 +144,7 @@ void Signature::ToString(std::stringstream &ss, const varbinder::Variable *varia ss << ": "; - (*it)->TsType()->ToString(ss); + (*it)->TsType()->ToString(ss, precise); if (std::next(it) != signatureInfo_->params.end()) { ss << ", "; @@ -157,7 +159,8 @@ void Signature::ToString(std::stringstream &ss, const varbinder::Variable *varia ss << "..."; ss << signatureInfo_->restVar->Name(); ss << ": "; - signatureInfo_->restVar->TsType()->ToString(ss); + signatureInfo_->restVar->TsType()->ToString(ss, precise); + ss << "[]"; } @@ -169,7 +172,14 @@ void Signature::ToString(std::stringstream &ss, const varbinder::Variable *varia ss << " => "; } - returnType_->ToString(ss); + returnType_->ToString(ss, precise); +} + +std::string Signature::ToString() const +{ + std::stringstream ss; + ToString(ss, nullptr); + return ss.str(); } namespace { @@ -190,9 +200,7 @@ std::size_t GetToCheckParamCount(Signature *signature, bool isEts) bool Signature::IdenticalParameter(TypeRelation *relation, Type *type1, Type *type2) { - if (!CheckFunctionalInterfaces(relation, type1, type2)) { - relation->IsIdenticalTo(type1, type2); - } + relation->IsIdenticalTo(type1, type2); return relation->IsTrue(); } @@ -340,4 +348,24 @@ void Signature::AssignmentTarget(TypeRelation *relation, Signature *source) relation->IsAssignableTo(source->RestVar()->TsType(), signatureInfo_->restVar->TsType()); } } + +Signature *Signature::BoxPrimitives(ETSChecker *checker) +{ + auto *allocator = checker->Allocator(); + auto *sigInfo = allocator->New(signatureInfo_, allocator); + for (auto param : sigInfo->params) { + if (param->TsType()->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { + param->SetTsType(checker->PrimitiveTypeAsETSBuiltinType(param->TsType())); + } + } + auto *retType = returnType_->HasTypeFlag(TypeFlag::ETS_PRIMITIVE) + ? checker->PrimitiveTypeAsETSBuiltinType(returnType_) + : returnType_; + + auto *resultSig = allocator->New(sigInfo, retType, func_); + resultSig->flags_ = flags_; + resultSig->SetOwner(Owner()); + resultSig->SetOwnerVar(OwnerVar()); + return resultSig; +} } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/signature.h b/ets2panda/checker/types/signature.h index 295dd1111c72bc314a60d4850aa44811c78aa7d7..ab2bc277fcc51a5cf498cc0ebbe2afbfa3cab70f 100644 --- a/ets2panda/checker/types/signature.h +++ b/ets2panda/checker/types/signature.h @@ -81,6 +81,8 @@ enum class SignatureFlags : uint32_t { THIS_RETURN_TYPE = 1U << 15U, GETTER = 1U << 16U, SETTER = 1U << 17U, + THROWS = 1U << 18U, + RETHROWS = 1U << 19U, INTERNAL_PROTECTED = INTERNAL | PROTECTED, GETTER_OR_SETTER = GETTER | SETTER, @@ -245,10 +247,13 @@ public: Signature *Copy(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes); Signature *Substitute(TypeRelation *relation, const Substitution *substitution); - void ToString(std::stringstream &ss, const varbinder::Variable *variable, bool printAsMethod = false) const; + void ToString(std::stringstream &ss, const varbinder::Variable *variable, bool printAsMethod = false, + bool precise = false) const; + std::string ToString() const; void Identical(TypeRelation *relation, Signature *other); bool CheckFunctionalInterfaces(TypeRelation *relation, Type *source, Type *target); void AssignmentTarget(TypeRelation *relation, Signature *source); + Signature *BoxPrimitives(ETSChecker *checker); private: bool IdenticalParameter(TypeRelation *relation, Type *type1, Type *type2); diff --git a/ets2panda/checker/types/ts/anyType.cpp b/ets2panda/checker/types/ts/anyType.cpp index 8409060e97205aca44075ab32a21ba5bd9d42e36..db2c7f04207d3c58643f4aec71d2d552bc3ad81d 100644 --- a/ets2panda/checker/types/ts/anyType.cpp +++ b/ets2panda/checker/types/ts/anyType.cpp @@ -16,7 +16,7 @@ #include "anyType.h" namespace panda::es2panda::checker { -void AnyType::ToString(std::stringstream &ss) const +void AnyType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "any"; } diff --git a/ets2panda/checker/types/ts/anyType.h b/ets2panda/checker/types/ts/anyType.h index 69c36c85f551be9052bfd885ea95122dda26c0a1..19633bc7a504bea3a6da49ae9c6c6c93a7f05d0c 100644 --- a/ets2panda/checker/types/ts/anyType.h +++ b/ets2panda/checker/types/ts/anyType.h @@ -23,7 +23,7 @@ class AnyType : public Type { public: AnyType() : Type(TypeFlag::ANY) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; diff --git a/ets2panda/checker/types/ts/arrayType.cpp b/ets2panda/checker/types/ts/arrayType.cpp index 8c4e2ac9b752354e21737cf0b8795727369a01e1..2e3457208810c901a93e1f9999627e44b7951c1a 100644 --- a/ets2panda/checker/types/ts/arrayType.cpp +++ b/ets2panda/checker/types/ts/arrayType.cpp @@ -19,13 +19,13 @@ #include "checker/types/ts/objectType.h" namespace panda::es2panda::checker { -void ArrayType::ToString(std::stringstream &ss) const +void ArrayType::ToString(std::stringstream &ss, bool precise) const { bool elemIsUnion = (element_->TypeFlags() == TypeFlag::UNION); if (elemIsUnion) { ss << "("; } - ElementType()->ToString(ss); + ElementType()->ToString(ss, precise); if (elemIsUnion) { ss << ")"; } diff --git a/ets2panda/checker/types/ts/arrayType.h b/ets2panda/checker/types/ts/arrayType.h index 78f6c259941b962ce68e4557492ce96c924604af..d60de37a4d12828ca1cef9a07178a7826f310f8b 100644 --- a/ets2panda/checker/types/ts/arrayType.h +++ b/ets2panda/checker/types/ts/arrayType.h @@ -33,7 +33,7 @@ public: return element_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/bigintLiteralType.cpp b/ets2panda/checker/types/ts/bigintLiteralType.cpp index b378c83fc57c839369b1177dc9438abfb3e14f5e..66235052588ea9eef635d77296915368afb7c58e 100644 --- a/ets2panda/checker/types/ts/bigintLiteralType.cpp +++ b/ets2panda/checker/types/ts/bigintLiteralType.cpp @@ -16,7 +16,7 @@ #include "bigintLiteralType.h" namespace panda::es2panda::checker { -void BigintLiteralType::ToString(std::stringstream &ss) const +void BigintLiteralType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << value_; } diff --git a/ets2panda/checker/types/ts/bigintLiteralType.h b/ets2panda/checker/types/ts/bigintLiteralType.h index 9e02187ffe506f858727b9249d8ad19e5929550e..b3797e5affa0355623896e14f0af58f8c3bdfb12 100644 --- a/ets2panda/checker/types/ts/bigintLiteralType.h +++ b/ets2panda/checker/types/ts/bigintLiteralType.h @@ -36,7 +36,7 @@ public: return negative_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void ToStringAsSrc(std::stringstream &ss) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/bigintType.cpp b/ets2panda/checker/types/ts/bigintType.cpp index 91e816019d653586ad6d32c38f9a45e4c43af992..ee84c0717acc6695430e86467b7b0c739f7aa987 100644 --- a/ets2panda/checker/types/ts/bigintType.cpp +++ b/ets2panda/checker/types/ts/bigintType.cpp @@ -16,7 +16,7 @@ #include "bigintType.h" namespace panda::es2panda::checker { -void BigintType::ToString(std::stringstream &ss) const +void BigintType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "bigint"; } diff --git a/ets2panda/checker/types/ts/bigintType.h b/ets2panda/checker/types/ts/bigintType.h index 17b7526c605661d7c0e351c262ba3533d2dd3bf4..e9b839d3e59fcbcaecc8fe478fbf098ba2b26dbe 100644 --- a/ets2panda/checker/types/ts/bigintType.h +++ b/ets2panda/checker/types/ts/bigintType.h @@ -23,7 +23,7 @@ class BigintType : public Type { public: BigintType() : Type(TypeFlag::BIGINT) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/booleanLiteralType.cpp b/ets2panda/checker/types/ts/booleanLiteralType.cpp index b204f0b5060976567a27cbab45f638097d667f2f..36a06893425d149f434b237533f82f9759dace14 100644 --- a/ets2panda/checker/types/ts/booleanLiteralType.cpp +++ b/ets2panda/checker/types/ts/booleanLiteralType.cpp @@ -16,7 +16,7 @@ #include "booleanLiteralType.h" namespace panda::es2panda::checker { -void BooleanLiteralType::ToString(std::stringstream &ss) const +void BooleanLiteralType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { if (value_) { ss << "true"; diff --git a/ets2panda/checker/types/ts/booleanLiteralType.h b/ets2panda/checker/types/ts/booleanLiteralType.h index 381df49bc45d8cb5be675fc8aa13bb9a7e4aa752..4c04e0cdeaad4ce53f6920d420da70c6623c6f6b 100644 --- a/ets2panda/checker/types/ts/booleanLiteralType.h +++ b/ets2panda/checker/types/ts/booleanLiteralType.h @@ -28,7 +28,7 @@ public: return value_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void ToStringAsSrc(std::stringstream &ss) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/booleanType.cpp b/ets2panda/checker/types/ts/booleanType.cpp index 3ba7501e333db432fb04e7319481ba6117c59a60..3855d633b11b092e6c9ff21103b1955713b32635 100644 --- a/ets2panda/checker/types/ts/booleanType.cpp +++ b/ets2panda/checker/types/ts/booleanType.cpp @@ -16,7 +16,7 @@ #include "booleanType.h" namespace panda::es2panda::checker { -void BooleanType::ToString(std::stringstream &ss) const +void BooleanType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "boolean"; } diff --git a/ets2panda/checker/types/ts/booleanType.h b/ets2panda/checker/types/ts/booleanType.h index b0b54f22330367a8bc95403c58d799f91a7b2991..3dc6c1ece33ef757e992d0621cd87e4efd3066a7 100644 --- a/ets2panda/checker/types/ts/booleanType.h +++ b/ets2panda/checker/types/ts/booleanType.h @@ -23,7 +23,7 @@ class BooleanType : public Type { public: BooleanType() : Type(TypeFlag::BOOLEAN) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/constructorType.cpp b/ets2panda/checker/types/ts/constructorType.cpp index 75596cb0b99b9ae81bfd987dbc11dba0456e40a5..294d1a28a53b0ece3a182ac941f44bcf9bf7e1b5 100644 --- a/ets2panda/checker/types/ts/constructorType.cpp +++ b/ets2panda/checker/types/ts/constructorType.cpp @@ -18,7 +18,7 @@ #include "checker/types/signature.h" namespace panda::es2panda::checker { -void ConstructorType::ToString(std::stringstream &ss) const +void ConstructorType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { if (desc_->constructSignatures.size() > 1) { ss << "{ "; diff --git a/ets2panda/checker/types/ts/constructorType.h b/ets2panda/checker/types/ts/constructorType.h index 4c930cee425ce0e369eee677a3dd9dc3867c3c02..02389c7292771e2085257e0811229b28518e810d 100644 --- a/ets2panda/checker/types/ts/constructorType.h +++ b/ets2panda/checker/types/ts/constructorType.h @@ -23,7 +23,7 @@ class ConstructorType : public ObjectType { public: explicit ConstructorType(ObjectDescriptor *desc) : ObjectType(ObjectType::ObjectTypeKind::FUNCTION, desc) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; TypeFacts GetTypeFacts() const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; }; diff --git a/ets2panda/checker/types/ts/enumLiteralType.cpp b/ets2panda/checker/types/ts/enumLiteralType.cpp index 7cd7c05dc8b3871300b5406a97c0396361974757..0618f2d1c936919c2ef5e7a83da3b3ad4a366095 100644 --- a/ets2panda/checker/types/ts/enumLiteralType.cpp +++ b/ets2panda/checker/types/ts/enumLiteralType.cpp @@ -19,7 +19,7 @@ #include "checker/types/ts/enumType.h" namespace panda::es2panda::checker { -void EnumLiteralType::ToString(std::stringstream &ss) const +void EnumLiteralType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << name_; } diff --git a/ets2panda/checker/types/ts/enumLiteralType.h b/ets2panda/checker/types/ts/enumLiteralType.h index 83a42455efe5a1222ce4c5ccdf7c09c7e9743cd9..19e4e8c9d57cadc99f37ca5d1104850c86b7434f 100644 --- a/ets2panda/checker/types/ts/enumLiteralType.h +++ b/ets2panda/checker/types/ts/enumLiteralType.h @@ -47,7 +47,7 @@ public: return kind_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void ToStringAsSrc(std::stringstream &ss) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/enumType.cpp b/ets2panda/checker/types/ts/enumType.cpp index 0ee4cc675ac9f14d20d1b3c4cdbd58a2b9985384..4a308dda73ebdb778f83e2de770b6392400a17cb 100644 --- a/ets2panda/checker/types/ts/enumType.cpp +++ b/ets2panda/checker/types/ts/enumType.cpp @@ -18,7 +18,7 @@ #include "varbinder/variable.h" namespace panda::es2panda::checker { -void EnumType::ToString(std::stringstream &ss) const +void EnumType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << enumLiteralVar_->Name() << "." << enumVar_->Name(); } diff --git a/ets2panda/checker/types/ts/enumType.h b/ets2panda/checker/types/ts/enumType.h index c1a3a87882a5bc3c5bdf0281e80adf3ab3004b46..ce3da03261a2a763a6f50932e7c02f91dd17f0e6 100644 --- a/ets2panda/checker/types/ts/enumType.h +++ b/ets2panda/checker/types/ts/enumType.h @@ -1,3 +1,4 @@ + /** * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,7 +41,7 @@ public: return enumVar_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/functionType.cpp b/ets2panda/checker/types/ts/functionType.cpp index 3e1897429192a54666fe25d69b6bf804bba72e03..e8a10afe9dfc80a9a85d51e8f396a63fdd8a55c0 100644 --- a/ets2panda/checker/types/ts/functionType.cpp +++ b/ets2panda/checker/types/ts/functionType.cpp @@ -18,7 +18,7 @@ #include "checker/types/signature.h" namespace panda::es2panda::checker { -void FunctionType::ToString(std::stringstream &ss) const +void FunctionType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { static std::unordered_set stack; diff --git a/ets2panda/checker/types/ts/functionType.h b/ets2panda/checker/types/ts/functionType.h index f1b465a54bf29dc70687363036581e95c8d9aac3..b8e36d821d176a95143ad032041d23f8e2e35a14 100644 --- a/ets2panda/checker/types/ts/functionType.h +++ b/ets2panda/checker/types/ts/functionType.h @@ -24,7 +24,7 @@ class FunctionType : public ObjectType { public: explicit FunctionType(ObjectDescriptor *desc) : ObjectType(ObjectType::ObjectTypeKind::FUNCTION, desc) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; TypeFacts GetTypeFacts() const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; }; diff --git a/ets2panda/checker/types/ts/interfaceType.cpp b/ets2panda/checker/types/ts/interfaceType.cpp index 69b95e8ce3fa99201b78e0f45c3a71547cc09dff..633009c8a1c9f2b5e79eaab173cc0403cb14ba17 100644 --- a/ets2panda/checker/types/ts/interfaceType.cpp +++ b/ets2panda/checker/types/ts/interfaceType.cpp @@ -23,7 +23,7 @@ #include namespace panda::es2panda::checker { -void InterfaceType::ToString(std::stringstream &ss) const +void InterfaceType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << name_; diff --git a/ets2panda/checker/types/ts/interfaceType.h b/ets2panda/checker/types/ts/interfaceType.h index cfd1811e4929f73ca6f38afac6c946a4cb988514..210129214b984fe945987e091c35f8e085787f50 100644 --- a/ets2panda/checker/types/ts/interfaceType.h +++ b/ets2panda/checker/types/ts/interfaceType.h @@ -128,7 +128,7 @@ public: return properties; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; TypeFacts GetTypeFacts() const override; void Identical(TypeRelation *relation, Type *other) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; diff --git a/ets2panda/checker/types/ts/neverType.cpp b/ets2panda/checker/types/ts/neverType.cpp index e4d75b636209194b65062c0225ef856e279dea7e..8add433de854dccac13d148fd0bebbedf0b54a98 100644 --- a/ets2panda/checker/types/ts/neverType.cpp +++ b/ets2panda/checker/types/ts/neverType.cpp @@ -16,7 +16,7 @@ #include "neverType.h" namespace panda::es2panda::checker { -void NeverType::ToString(std::stringstream &ss) const +void NeverType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "never"; } diff --git a/ets2panda/checker/types/ts/neverType.h b/ets2panda/checker/types/ts/neverType.h index 0931b3ae44735a9a18df449e57b1441a0eeadc54..5a5fb981c3a982b714a97ba72fd49d2ce1e28af6 100644 --- a/ets2panda/checker/types/ts/neverType.h +++ b/ets2panda/checker/types/ts/neverType.h @@ -23,7 +23,7 @@ class NeverType : public Type { public: NeverType() : Type(TypeFlag::NEVER) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; TypeFacts GetTypeFacts() const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/nonPrimitiveType.cpp b/ets2panda/checker/types/ts/nonPrimitiveType.cpp index 3c37b7cebf616752f57400ba6cc60ba93c148969..3fb42a30de6324a6b176b4ff3ae39bdfc5ad4bdc 100644 --- a/ets2panda/checker/types/ts/nonPrimitiveType.cpp +++ b/ets2panda/checker/types/ts/nonPrimitiveType.cpp @@ -16,7 +16,7 @@ #include "nonPrimitiveType.h" namespace panda::es2panda::checker { -void NonPrimitiveType::ToString(std::stringstream &ss) const +void NonPrimitiveType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "object"; } diff --git a/ets2panda/checker/types/ts/nonPrimitiveType.h b/ets2panda/checker/types/ts/nonPrimitiveType.h index 2047f5df5758e9cd93c2800663f26de5396ced43..614a658ad564cf7c55c325a8f8d1f4696ef6c73b 100644 --- a/ets2panda/checker/types/ts/nonPrimitiveType.h +++ b/ets2panda/checker/types/ts/nonPrimitiveType.h @@ -23,7 +23,7 @@ class NonPrimitiveType : public Type { public: NonPrimitiveType() : Type(TypeFlag::NON_PRIMITIVE) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; TypeFacts GetTypeFacts() const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/nullType.cpp b/ets2panda/checker/types/ts/nullType.cpp index 786aed31c6edb2cabe6bd3db889c555825a3d8b1..bcd90b3f70038cf0d1c66ee21e1ea09d1edaf72b 100644 --- a/ets2panda/checker/types/ts/nullType.cpp +++ b/ets2panda/checker/types/ts/nullType.cpp @@ -16,7 +16,7 @@ #include "nullType.h" namespace panda::es2panda::checker { -void NullType::ToString(std::stringstream &ss) const +void NullType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "null"; } diff --git a/ets2panda/checker/types/ts/nullType.h b/ets2panda/checker/types/ts/nullType.h index c46dfccb24b06b26942881de22e734eceee7cb84..5d40915809a2715623aef50ba5be3ca4a3d65764 100644 --- a/ets2panda/checker/types/ts/nullType.h +++ b/ets2panda/checker/types/ts/nullType.h @@ -23,7 +23,7 @@ class NullType : public Type { public: NullType() : Type(TypeFlag::NULL_TYPE) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/numberLiteralType.cpp b/ets2panda/checker/types/ts/numberLiteralType.cpp index c4ccc26e3705309d897f318bbac4628356679e73..3bc17ad8bc4dd1b17666589524f270b38b8d2557 100644 --- a/ets2panda/checker/types/ts/numberLiteralType.cpp +++ b/ets2panda/checker/types/ts/numberLiteralType.cpp @@ -20,7 +20,7 @@ #include "checker/types/ts/enumType.h" namespace panda::es2panda::checker { -void NumberLiteralType::ToString(std::stringstream &ss) const +void NumberLiteralType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << util::Helpers::ToString(value_); } diff --git a/ets2panda/checker/types/ts/numberLiteralType.h b/ets2panda/checker/types/ts/numberLiteralType.h index 360060a925771989c3b636a9040115dd3a9389a2..8b738425b7050e7b511e90faae139d7f4682dbee 100644 --- a/ets2panda/checker/types/ts/numberLiteralType.h +++ b/ets2panda/checker/types/ts/numberLiteralType.h @@ -28,7 +28,7 @@ public: return value_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void ToStringAsSrc(std::stringstream &ss) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/numberType.cpp b/ets2panda/checker/types/ts/numberType.cpp index 40916929fd36efa53f8b84f08efbe1e07bbe1ae9..59e90af296985c0e3b1b05ba9410273267f83779 100644 --- a/ets2panda/checker/types/ts/numberType.cpp +++ b/ets2panda/checker/types/ts/numberType.cpp @@ -19,7 +19,7 @@ #include "checker/types/ts/enumType.h" namespace panda::es2panda::checker { -void NumberType::ToString(std::stringstream &ss) const +void NumberType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "number"; } diff --git a/ets2panda/checker/types/ts/numberType.h b/ets2panda/checker/types/ts/numberType.h index a30f48609f8154c91348d1be2bb20ac4500146a9..eedbc33fe040eabef099597cbce2d85f20aeae76 100644 --- a/ets2panda/checker/types/ts/numberType.h +++ b/ets2panda/checker/types/ts/numberType.h @@ -23,7 +23,7 @@ class NumberType : public Type { public: NumberType() : Type(TypeFlag::NUMBER) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/objectLiteralType.cpp b/ets2panda/checker/types/ts/objectLiteralType.cpp index 407454989dfb19651344006e86e4656fa6563514..0bedc56068b34e87c19d40531bcd7328d496f7e4 100644 --- a/ets2panda/checker/types/ts/objectLiteralType.cpp +++ b/ets2panda/checker/types/ts/objectLiteralType.cpp @@ -22,7 +22,7 @@ namespace panda::es2panda::checker { class TSChecker; -void ObjectLiteralType::ToString(std::stringstream &ss) const +void ObjectLiteralType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "{ "; diff --git a/ets2panda/checker/types/ts/objectLiteralType.h b/ets2panda/checker/types/ts/objectLiteralType.h index e9b5695c1c07ce046180a7f0065239b2ee4f9b4f..85feba1c5c619c84a79b76959af7d53fe5c00f57 100644 --- a/ets2panda/checker/types/ts/objectLiteralType.h +++ b/ets2panda/checker/types/ts/objectLiteralType.h @@ -24,7 +24,7 @@ public: explicit ObjectLiteralType(ObjectDescriptor *desc) : ObjectType(ObjectType::ObjectTypeKind::LITERAL, desc) {} ObjectLiteralType() : ObjectType(ObjectType::ObjectTypeKind::LITERAL) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; TypeFacts GetTypeFacts() const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; }; diff --git a/ets2panda/checker/types/ts/stringLiteralType.cpp b/ets2panda/checker/types/ts/stringLiteralType.cpp index 87f8cea1c18409ef9dd31e402f2db895f0c60722..c5e6c80e2eb2e28c8078a65b4c7ba6222faef9e6 100644 --- a/ets2panda/checker/types/ts/stringLiteralType.cpp +++ b/ets2panda/checker/types/ts/stringLiteralType.cpp @@ -16,7 +16,7 @@ #include "stringLiteralType.h" namespace panda::es2panda::checker { -void StringLiteralType::ToString(std::stringstream &ss) const +void StringLiteralType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "\"" << value_ << "\""; } diff --git a/ets2panda/checker/types/ts/stringLiteralType.h b/ets2panda/checker/types/ts/stringLiteralType.h index f18e1cb63b8ebf23dbd2fb2601218702e417efbb..fbca9751a9e5a2a35ee265061110194e777c20c5 100644 --- a/ets2panda/checker/types/ts/stringLiteralType.h +++ b/ets2panda/checker/types/ts/stringLiteralType.h @@ -28,7 +28,7 @@ public: return value_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void ToStringAsSrc(std::stringstream &ss) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/stringType.cpp b/ets2panda/checker/types/ts/stringType.cpp index 9afedd90b61d6c8d86aaf6e5c4b509396400cf26..e0b4a9182b3c4126bfdccd7b5a93eef6d5a047b8 100644 --- a/ets2panda/checker/types/ts/stringType.cpp +++ b/ets2panda/checker/types/ts/stringType.cpp @@ -16,7 +16,7 @@ #include "stringType.h" namespace panda::es2panda::checker { -void StringType::ToString(std::stringstream &ss) const +void StringType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "string"; } diff --git a/ets2panda/checker/types/ts/stringType.h b/ets2panda/checker/types/ts/stringType.h index d37ae5b48ddb3c422b038f2f695a29695190e829..2081adda400843413e3de57ae4ce57a608010320 100644 --- a/ets2panda/checker/types/ts/stringType.h +++ b/ets2panda/checker/types/ts/stringType.h @@ -23,7 +23,7 @@ class StringType : public Type { public: StringType() : Type(TypeFlag::STRING) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/tupleType.cpp b/ets2panda/checker/types/ts/tupleType.cpp index 9e5de1369e137b31bd658a38e5643fe8e3e93637..9efd5ccb6702a871fa7eccd0ead6a5468e12aac1 100644 --- a/ets2panda/checker/types/ts/tupleType.cpp +++ b/ets2panda/checker/types/ts/tupleType.cpp @@ -30,7 +30,7 @@ Type *TupleType::ConvertToArrayType(TSChecker *checker) return checker->Allocator()->New(arrayType); } -void TupleType::ToString(std::stringstream &ss) const +void TupleType::ToString(std::stringstream &ss, bool precise) const { if (readonly_) { ss << "readonly "; @@ -39,7 +39,7 @@ void TupleType::ToString(std::stringstream &ss) const if (namedMembers_.empty()) { for (auto it = desc_->properties.begin(); it != desc_->properties.end(); it++) { - (*it)->TsType()->ToString(ss); + (*it)->TsType()->ToString(ss, precise); if ((*it)->HasFlag(varbinder::VariableFlags::OPTIONAL)) { ss << "?"; } @@ -58,7 +58,7 @@ void TupleType::ToString(std::stringstream &ss) const } ss << ": "; - (*it)->TsType()->ToString(ss); + (*it)->TsType()->ToString(ss, precise); if (std::next(it) != desc_->properties.end()) { ss << ", "; } diff --git a/ets2panda/checker/types/ts/tupleType.h b/ets2panda/checker/types/ts/tupleType.h index 53fc5c47fc0be3cff90c570ee9d979580c334e1e..b638dce06ed1547ba3aba42a06a636e45212b371 100644 --- a/ets2panda/checker/types/ts/tupleType.h +++ b/ets2panda/checker/types/ts/tupleType.h @@ -87,7 +87,7 @@ public: Type *ConvertToArrayType(TSChecker *checker); - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/typeParameter.cpp b/ets2panda/checker/types/ts/typeParameter.cpp index 516b284db4679e82910212114d6e052f7dc768f5..fb297bfbf3e0b084f597349723097fc5c66e5e95 100644 --- a/ets2panda/checker/types/ts/typeParameter.cpp +++ b/ets2panda/checker/types/ts/typeParameter.cpp @@ -16,7 +16,7 @@ #include "typeParameter.h" namespace panda::es2panda::checker { -void TypeParameter::ToString([[maybe_unused]] std::stringstream &ss) const +void TypeParameter::ToString([[maybe_unused]] std::stringstream &ss, [[maybe_unused]] bool precise) const { UNREACHABLE(); } diff --git a/ets2panda/checker/types/ts/typeParameter.h b/ets2panda/checker/types/ts/typeParameter.h index bcc320265a19204985bc0ccded22d64afd7e2069..3de782e2c18d1fa29dd8f8ad8d0114090c5f8c44 100644 --- a/ets2panda/checker/types/ts/typeParameter.h +++ b/ets2panda/checker/types/ts/typeParameter.h @@ -46,7 +46,7 @@ public: default_ = type; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/typeReference.cpp b/ets2panda/checker/types/ts/typeReference.cpp index 579f22f3838cc9aa565200f24009ec7d24c1aaf8..4ec359bb587777c14d2c2a2196b55cf97e1f3e94 100644 --- a/ets2panda/checker/types/ts/typeReference.cpp +++ b/ets2panda/checker/types/ts/typeReference.cpp @@ -16,10 +16,10 @@ #include "typeReference.h" namespace panda::es2panda::checker { -void TypeReference::ToString(std::stringstream &ss) const +void TypeReference::ToString(std::stringstream &ss, bool precise) const { if (*ref_ != nullptr) { - (*ref_)->ToString(ss); + (*ref_)->ToString(ss, precise); } } diff --git a/ets2panda/checker/types/ts/typeReference.h b/ets2panda/checker/types/ts/typeReference.h index 2b4f33fc18a92457104961ce9bf913d338cfd55b..4e3022e7a4e4571faa36f7668c862f3b59e1e952 100644 --- a/ets2panda/checker/types/ts/typeReference.h +++ b/ets2panda/checker/types/ts/typeReference.h @@ -33,7 +33,7 @@ public: return *ref_; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ts/undefinedType.cpp b/ets2panda/checker/types/ts/undefinedType.cpp index 5e7f6aeae367b58dcb5b91a96ca5eed5d8ce0f2b..72e47c96e7eb9ea7fa9eb026aecf498c20502337 100644 --- a/ets2panda/checker/types/ts/undefinedType.cpp +++ b/ets2panda/checker/types/ts/undefinedType.cpp @@ -16,7 +16,7 @@ #include "undefinedType.h" namespace panda::es2panda::checker { -void UndefinedType::ToString(std::stringstream &ss) const +void UndefinedType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "undefined"; } diff --git a/ets2panda/checker/types/ts/undefinedType.h b/ets2panda/checker/types/ts/undefinedType.h index 79fbceeb63fae48f11ea7afbfa30d14e1b2dfab7..93a0db73c9402ef96b07458da936078a89059ff9 100644 --- a/ets2panda/checker/types/ts/undefinedType.h +++ b/ets2panda/checker/types/ts/undefinedType.h @@ -23,7 +23,7 @@ class UndefinedType : public Type { public: UndefinedType() : Type(TypeFlag::UNDEFINED) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/unionType.cpp b/ets2panda/checker/types/ts/unionType.cpp index 1d3f7e92f11954b0e50ec4e6f9b5c1927c967afd..352436e9cf46da823c024a422e2ea598e25f52b8 100644 --- a/ets2panda/checker/types/ts/unionType.cpp +++ b/ets2panda/checker/types/ts/unionType.cpp @@ -19,10 +19,10 @@ #include "checker/types/globalTypesHolder.h" namespace panda::es2panda::checker { -void UnionType::ToString(std::stringstream &ss) const +void UnionType::ToString(std::stringstream &ss, bool precise) const { for (auto it = constituentTypes_.begin(); it != constituentTypes_.end(); it++) { - (*it)->ToString(ss); + (*it)->ToString(ss, precise); if (std::next(it) != constituentTypes_.end()) { ss << " | "; } diff --git a/ets2panda/checker/types/ts/unionType.h b/ets2panda/checker/types/ts/unionType.h index 95d81fc732b3c82d4557f25c8228426fa784852c..93ea3ced44b52f0b537393e7b2799c4df40b2bb6 100644 --- a/ets2panda/checker/types/ts/unionType.h +++ b/ets2panda/checker/types/ts/unionType.h @@ -114,7 +114,7 @@ public: mergedObjectType_ = type; } - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; diff --git a/ets2panda/checker/types/ts/unknownType.cpp b/ets2panda/checker/types/ts/unknownType.cpp index 554a3b8e0e9bcce45ce7c0046b22995f7f33428f..e3f0af57c5e82629d3883d7f398bdb27e921823a 100644 --- a/ets2panda/checker/types/ts/unknownType.cpp +++ b/ets2panda/checker/types/ts/unknownType.cpp @@ -16,7 +16,7 @@ #include "unknownType.h" namespace panda::es2panda::checker { -void UnknownType::ToString(std::stringstream &ss) const +void UnknownType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "unknown"; } diff --git a/ets2panda/checker/types/ts/unknownType.h b/ets2panda/checker/types/ts/unknownType.h index d1cb778f354f361ec36f7636d52fd1c7c03324d9..5a762dbe7fc0c8a60f361cb6f0180fca01d09f97 100644 --- a/ets2panda/checker/types/ts/unknownType.h +++ b/ets2panda/checker/types/ts/unknownType.h @@ -23,7 +23,7 @@ class UnknownType : public Type { public: UnknownType() : Type(TypeFlag::UNKNOWN) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; TypeFacts GetTypeFacts() const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ts/voidType.cpp b/ets2panda/checker/types/ts/voidType.cpp index cb2b2fe4035c380b6b3c7762c0f8786476310eef..edab990222dce37ae37ffc8e40a6332da7c60321 100644 --- a/ets2panda/checker/types/ts/voidType.cpp +++ b/ets2panda/checker/types/ts/voidType.cpp @@ -16,7 +16,7 @@ #include "voidType.h" namespace panda::es2panda::checker { -void VoidType::ToString(std::stringstream &ss) const +void VoidType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const { ss << "void"; } diff --git a/ets2panda/checker/types/ts/voidType.h b/ets2panda/checker/types/ts/voidType.h index 47a5ceb8074dc66413fa602c01150f09e195b00c..e7b1b39b494094e641090c7720c6ab61ebc75194 100644 --- a/ets2panda/checker/types/ts/voidType.h +++ b/ets2panda/checker/types/ts/voidType.h @@ -23,7 +23,7 @@ class VoidType : public Type { public: VoidType() : Type(TypeFlag::VOID) {} - void ToString(std::stringstream &ss) const override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; TypeFacts GetTypeFacts() const override; void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/type.cpp b/ets2panda/checker/types/type.cpp index 81affaf07a021118950650f48d0f34bb840b6f0d..ddf5db1e185d990fa5b8f9333c320e53ab80e4ec 100644 --- a/ets2panda/checker/types/type.cpp +++ b/ets2panda/checker/types/type.cpp @@ -83,11 +83,37 @@ bool Type::IsLambdaObject() const return false; } +void Type::ToString(std::stringstream &ss) const +{ + ToString(ss, false); +} + void Type::ToStringAsSrc(std::stringstream &ss) const { ToString(ss); } +std::string Type::ToString() const +{ + std::stringstream ss; + ToString(ss); + return ss.str(); +} + +std::string Type::ToStringAsSrc() const +{ + std::stringstream ss; + ToStringAsSrc(ss); + return ss.str(); +} + +std::string Type::ToStringPrecise() const +{ + std::stringstream ss; + ToString(ss, true); + return ss.str(); +} + void Type::Identical(TypeRelation *relation, Type *other) { relation->Result(typeFlags_ == other->TypeFlags()); @@ -140,4 +166,5 @@ Type *Type::Substitute([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] { return this; } + } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index 455ec1e227c8a225cbe77ce5efe4b679d154adb3..446da59ccb17f117b85ffcdcee396a8f811f8808 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -224,8 +224,13 @@ public: } bool IsLambdaObject() const; - virtual void ToString(std::stringstream &ss) const = 0; + virtual void ToString(std::stringstream &ss, bool precise) const = 0; + void ToString(std::stringstream &ss) const; + std::string ToString() const; + std::string ToStringPrecise() const; virtual void ToStringAsSrc(std::stringstream &ss) const; + std::string ToStringAsSrc() const; + virtual TypeFacts GetTypeFacts() const; virtual void ToAssemblerType([[maybe_unused]] std::stringstream &ss) const {}; virtual void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const {}; diff --git a/ets2panda/checker/types/typeFlag.h b/ets2panda/checker/types/typeFlag.h index e4a973560db05f2f57ddb73cdd31c2478d82762e..821b89da24cd27a8cfb27add951990a8d3c0aa8d 100644 --- a/ets2panda/checker/types/typeFlag.h +++ b/ets2panda/checker/types/typeFlag.h @@ -129,7 +129,7 @@ enum class TypeFlag : uint64_t { VALID_ARITHMETIC_TYPE = ANY | NUMBER_LIKE | BIGINT_LIKE | ENUM, UNIT = LITERAL | UNIQUE_SYMBOL | NULLISH, GETTER_SETTER = GETTER | SETTER, - CONDITION_EXPRESSION_TYPE = NULLISH | CONSTANT | ETS_OBJECT | BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | + CONDITION_EXPRESSION_TYPE = NULLISH | CONSTANT | ETS_OBJECT | BYTE | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | ETS_BOOLEAN | ETS_ARRAY | ETS_ENUM | ETS_STRING_ENUM }; diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index fd2476ce9496e76741c94c109991d3215a2d3eec..bd6143b2512e31a63cc2069cf8e246372df888d9 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -15,8 +15,9 @@ #include "ETSCompiler.h" -#include "checker/types/ets/etsDynamicFunctionType.h" #include "compiler/base/catchTable.h" +#include "checker/types/ets/etsDynamicFunctionType.h" +#include "checker/types/ets/etsObjectType.h" #include "checker/types/ts/enumLiteralType.h" #include "compiler/base/condition.h" #include "compiler/base/lreference.h" @@ -328,9 +329,7 @@ void ETSCompiler::Compile(const ir::ETSNewClassInstanceExpression *expr) const etsg->InitObject(expr, expr->signature_, expr->GetArguments()); } - if (expr->GetBoxingUnboxingFlags() == ir::BoxingUnboxingFlags::NONE) { - etsg->SetAccumulatorType(expr->TsType()); - } + etsg->SetAccumulatorType(expr->TsType()); } void ETSCompiler::Compile(const ir::ETSNewMultiDimArrayInstanceExpression *expr) const @@ -659,11 +658,12 @@ void ETSCompiler::Compile(const ir::BinaryExpression *expr) const etsg->Binary(expr, expr->OperatorType(), lhs); } -static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::CallExpression *expr) +static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::CallExpression *expr, + checker::Signature *signature) { - if (expr->Signature()->RestVar() != nullptr) { + if (signature->RestVar() != nullptr) { std::size_t const argumentCount = expr->Arguments().size(); - std::size_t const parameterCount = expr->Signature()->MinArgCount(); + std::size_t const parameterCount = signature->MinArgCount(); ASSERT(argumentCount >= parameterCount); auto &arguments = const_cast &>(expr->Arguments()); @@ -678,13 +678,37 @@ static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::C } auto *arrayExpression = checker->AllocNode(std::move(elements), checker->Allocator()); arrayExpression->SetParent(const_cast(expr)); - arrayExpression->SetTsType(expr->Signature()->RestVar()->TsType()); + arrayExpression->SetTsType(signature->RestVar()->TsType()); arguments.erase(expr->Arguments().begin() + parameterCount, expr->Arguments().end()); arguments.emplace_back(arrayExpression); } } } +void ConvertArgumentsForFunctionalCall(checker::ETSChecker *const checker, const ir::CallExpression *expr) +{ + std::size_t const argumentCount = expr->Arguments().size(); + auto &arguments = const_cast &>(expr->Arguments()); + auto *signature = expr->Signature(); + + for (size_t i = 0; i < argumentCount; i++) { + auto *paramType = checker->MaybeBoxedType( + i < signature->Params().size() ? signature->Params()[i] : signature->RestVar(), checker->Allocator()); + + auto *arg = arguments[i]; + auto *cast = checker->Allocator()->New(arg, nullptr, false); + arguments[i]->SetParent(cast); + cast->SetParent(const_cast(expr)); + cast->SetTsType(paramType); + + if (paramType->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + cast->AddBoxingUnboxingFlags(checker->GetBoxingFlag(paramType)); + } + + arguments[i] = cast; + } +} + void ETSCompiler::Compile(const ir::BlockExpression *expr) const { (void)expr; @@ -787,13 +811,15 @@ void ETSCompiler::CompileDynamic(const ir::CallExpression *expr, compiler::VReg etsg->StoreAccumulator(expr, dynParam2); etsg->CallDynamic(expr, calleeReg, dynParam2, expr->Signature(), expr->Arguments()); etsg->SetAccumulatorType(expr->Signature()->ReturnType()); + if (etsg->GetAccumulatorType() != expr->TsType()) { etsg->ApplyConversion(expr, expr->TsType()); } } // Helper function to avoid branching in non optional cases -void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, bool isStatic) const +void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, bool isStatic, + checker::Signature *signature, bool isReference) const { ETSGen *etsg = GetETSGen(); if (expr->Callee()->GetBoxingUnboxingFlags() != ir::BoxingUnboxingFlags::NONE) { @@ -804,14 +830,42 @@ void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calle } else if (expr->Signature()->HasSignatureFlag(checker::SignatureFlags::PRIVATE) || expr->IsETSConstructorCall() || (expr->Callee()->IsMemberExpression() && expr->Callee()->AsMemberExpression()->Object()->IsSuperExpression())) { - etsg->CallThisStatic(expr, calleeReg, expr->Signature(), expr->Arguments()); + etsg->CallThisStatic(expr, calleeReg, signature, expr->Arguments()); + } else { + etsg->CallThisVirtual(expr, calleeReg, signature, expr->Arguments()); + } + + if (isReference) { + etsg->CheckedReferenceNarrowing(expr, signature->ReturnType()); } else { - etsg->CallThisVirtual(expr, calleeReg, expr->Signature(), expr->Arguments()); + etsg->SetAccumulatorType(signature->ReturnType()); } etsg->GuardUncheckedType(expr, expr->UncheckedType(), expr->OptionalType()); } +static checker::Signature *ConvertArgumentsForFunctionReference(ETSGen *etsg, const ir::CallExpression *expr) +{ + checker::Signature *origSignature = expr->Signature(); + + auto *funcType = + origSignature->Owner() + ->GetOwnProperty(checker::FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME) + ->TsType() + ->AsETSFunctionType(); + ASSERT(funcType->CallSignatures().size() == 1); + checker::Signature *signature = funcType->CallSignatures()[0]; + + if (signature->ReturnType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + expr->AddBoxingUnboxingFlags(const_cast(etsg->Checker()->AsETSChecker()) + ->GetUnboxingFlag(signature->ReturnType())); + } + + ConvertArgumentsForFunctionalCall(const_cast(etsg->Checker()->AsETSChecker()), expr); + + return signature; +} + void ETSCompiler::Compile(const ir::CallExpression *expr) const { ETSGen *etsg = GetETSGen(); @@ -829,7 +883,12 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const bool isReference = expr->Signature()->HasSignatureFlag(checker::SignatureFlags::TYPE); bool isDynamic = expr->Callee()->TsType()->HasTypeFlag(checker::TypeFlag::ETS_DYNAMIC_FLAG); - ConvertRestArguments(const_cast(etsg->Checker()->AsETSChecker()), expr); + checker::Signature *signature = expr->Signature(); + if (isReference) { + signature = ConvertArgumentsForFunctionReference(etsg, expr); + } + + ConvertRestArguments(const_cast(etsg->Checker()->AsETSChecker()), expr, signature); if (isDynamic) { CompileDynamic(expr, calleeReg); @@ -838,24 +897,27 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const etsg->LoadThis(expr); etsg->StoreAccumulator(expr, calleeReg); } - EmitCall(expr, calleeReg, isStatic); + EmitCall(expr, calleeReg, isStatic, signature, isReference); } else if (!isReference && expr->Callee()->IsMemberExpression()) { if (!isStatic) { expr->Callee()->AsMemberExpression()->Object()->Compile(etsg); etsg->StoreAccumulator(expr, calleeReg); } - EmitCall(expr, calleeReg, isStatic); + EmitCall(expr, calleeReg, isStatic, signature, isReference); } else if (expr->Callee()->IsSuperExpression() || expr->Callee()->IsThisExpression()) { ASSERT(!isReference && expr->IsETSConstructorCall()); expr->Callee()->Compile(etsg); // ctor is not a value! etsg->SetVRegType(calleeReg, etsg->GetAccumulatorType()); - EmitCall(expr, calleeReg, isStatic); + EmitCall(expr, calleeReg, isStatic, signature, isReference); } else { ASSERT(isReference); etsg->CompileAndCheck(expr->Callee()); etsg->StoreAccumulator(expr, calleeReg); etsg->EmitMaybeOptional( - expr, [this, expr, isStatic, &calleeReg]() { this->EmitCall(expr, calleeReg, isStatic); }, + expr, + [this, expr, isStatic, &calleeReg, signature, isReference]() { + this->EmitCall(expr, calleeReg, isStatic, signature, isReference); + }, expr->IsOptional()); } } diff --git a/ets2panda/compiler/core/ETSCompiler.h b/ets2panda/compiler/core/ETSCompiler.h index 5421dde41f556632d1816b3a6b7d8629a288390a..4e0e04dbd3533afc6f9d663515873a6b8508c7cf 100644 --- a/ets2panda/compiler/core/ETSCompiler.h +++ b/ets2panda/compiler/core/ETSCompiler.h @@ -38,7 +38,8 @@ private: void CompileDynamic(const ir::CallExpression *expr, compiler::VReg &calleeReg) const; void CompileCastUnboxable(const ir::TSAsExpression *expr) const; void CompileCast(const ir::TSAsExpression *expr) const; - void EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, bool isStatic) const; + void EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, bool isStatic, + checker::Signature *signature, bool isReference) const; ETSGen *GetETSGen() const; }; diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 9274234954f7ee0ee3b3571792d2b28c79c2358b..c771dc9d13e46b5d1fce13cdbe05c5165b57cec1 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -1753,10 +1753,6 @@ void ETSGen::CastToDynamic(const ir::AstNode *node, const checker::ETSDynamicTyp methodName = compiler::Signatures::Dynamic::NewStringBuiltin(type->Language()); break; } - if (GetAccumulatorType()->IsLambdaObject()) { - methodName = Signatures::BUILTIN_JSRUNTIME_CREATE_LAMBDA_PROXY; - break; - } [[fallthrough]]; } case checker::TypeFlag::ETS_ARRAY: { @@ -2020,6 +2016,8 @@ void ETSGen::Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, L void ETSGen::BranchIfNullish([[maybe_unused]] const ir::AstNode *node, [[maybe_unused]] Label *ifNullish) { #ifdef PANDA_WITH_ETS + RegScope rs(this); + auto *const type = GetAccumulatorType(); if (!Checker()->MayHaveNulllikeValue(type)) { @@ -2056,6 +2054,8 @@ void ETSGen::BranchIfNullish([[maybe_unused]] const ir::AstNode *node, [[maybe_u void ETSGen::BranchIfNotNullish([[maybe_unused]] const ir::AstNode *node, [[maybe_unused]] Label *ifNotNullish) { #ifdef PANDA_WITH_ETS + RegScope rs(this); + auto *const type = GetAccumulatorType(); if (!Checker()->MayHaveNulllikeValue(type)) { @@ -2117,6 +2117,7 @@ void ETSGen::EmitNullishGuardian(const ir::AstNode *node) void ETSGen::EmitNullishException(const ir::AstNode *node) { + RegScope ra(this); VReg exception = StoreException(node); NewObject(node, exception, Signatures::BUILTIN_NULLPOINTER_EXCEPTION); CallThisStatic0(node, exception, Signatures::BUILTIN_NULLPOINTER_EXCEPTION_CTOR); diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index b1c5907351785069c931ff85b42de93fc4fc8891..eddd5851d07c39dc2bad70713ab05bf4eda075e4 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -213,8 +213,7 @@ public: template void ResolveConditionalResult(const ir::AstNode *node, [[maybe_unused]] Label *ifFalse) { - auto type = node->IsExpression() && !node->AsExpression()->IsUnaryExpression() ? node->AsExpression()->TsType() - : GetAccumulatorType(); + auto type = GetAccumulatorType(); if (type->IsETSBooleanType()) { return; } @@ -233,11 +232,7 @@ public: BranchIfNullish(node, ifNullish); } } - if (type->IsETSArrayType()) { - compiler::VReg objReg = AllocReg(); - StoreAccumulator(node, objReg); - LoadArrayLength(node, objReg); - } else if (type->IsETSObjectType()) { + if (type->IsETSArrayType() || type->IsETSObjectType() || type->IsETSUnionType()) { ResolveConditionalResultObject(node); } else { ResolveConditionalResultNumeric(node, ifFalse, &end); @@ -937,7 +932,7 @@ private: arguments[idx]->Compile(this); \ VReg arg##idx = AllocReg(); \ ApplyConversion(arguments[idx], nullptr); \ - ApplyConversionAndStoreAccumulator(arguments[idx], arg##idx, paramType##idx); + ApplyConversionAndStoreAccumulator(arguments[idx], arg##idx, paramType##idx) template void CallThisImpl(const ir::AstNode *const node, const VReg ctor, checker::Signature *const signature, @@ -970,11 +965,8 @@ private: break; } default: { - for (const auto *arg : arguments) { - auto ttctx = TargetTypeContext(this, arg->TsType()); - VReg argReg = AllocReg(); - arg->Compile(this); - StoreAccumulator(node, argReg); + for (size_t idx = 0; idx < arguments.size(); idx++) { + COMPILE_ARG(idx); } Rra().Emit(node, ctor, arguments.size() + 1, name, ctor); @@ -1078,11 +1070,8 @@ private: default: { VReg argStart = NextReg(); - for (const auto *arg : arguments) { - auto ttctx = TargetTypeContext(this, arg->TsType()); - VReg argReg = AllocReg(); - arg->Compile(this); - StoreAccumulator(node, argReg); + for (size_t idx = 0; idx < arguments.size(); idx++) { + COMPILE_ARG(idx); } Rra().Emit(node, argStart, arguments.size(), name, argStart); @@ -1100,7 +1089,7 @@ private: auto ttctx##idx = TargetTypeContext(this, paramType##idx); \ VReg arg##idx = AllocReg(); \ arguments[idx]->Compile(this); \ - ApplyConversionAndStoreAccumulator(arguments[idx], arg##idx, paramType##idx); + ApplyConversionAndStoreAccumulator(arguments[idx], arg##idx, paramType##idx) template void CallDynamicImpl(const ir::AstNode *node, VReg &obj, VReg ¶m2, checker::Signature *signature, diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index c0797950622c2fd8f0b8e17cf44e2c24bc607b68..a4b5949abc6d39373b2df201692c49ca2ce039dd 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -296,6 +296,60 @@ builtins: - name: DoubleBox package: PKG_STD_CORE ref: BUILTIN_DOUBLE_BOX + - name: Function0 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION0 + - name: Function1 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION1 + - name: Function2 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION2 + - name: Function3 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION3 + - name: Function4 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION4 + - name: Function5 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION5 + - name: Function6 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION6 + - name: Function7 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION7 + - name: Function8 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION8 + - name: Function9 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION9 + - name: Function10 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION10 + - name: Function11 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION11 + - name: Function12 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION12 + - name: Function13 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION13 + - name: Function14 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION14 + - name: Function15 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION15 + - name: Function16 + package: PKG_STD_CORE + ref: BUILTIN_FUNCTION16 + - name: FunctionN + package: PKG_STD_CORE + ref: BUILTIN_FUNCTIONN signatures: - callee: BUILTIN_OBJECT @@ -1030,12 +1084,6 @@ signatures: return_type: BUILTIN_VOID ref: BUILTIN_JSRUNTIME_INIT_DYNAMIC_NEW_CLASS - - callee: BUILTIN_JSRUNTIME - method_name: __createLambdaProxy - params: [BUILTIN_OBJECT] - return_type: BUILTIN_JSVALUE - ref: BUILTIN_JSRUNTIME_CREATE_LAMBDA_PROXY - - callee: BUILTIN_JSRUNTIME method_name: loadModule params: [BUILTIN_STRING] diff --git a/ets2panda/ir/ets/etsFunctionType.h b/ets2panda/ir/ets/etsFunctionType.h index 42f7323db5f68c696d1a719df092521ba6937f1c..a3245e053fb3fdddeb37ed9d12589685b1e34c8a 100644 --- a/ets2panda/ir/ets/etsFunctionType.h +++ b/ets2panda/ir/ets/etsFunctionType.h @@ -93,6 +93,11 @@ public: return (funcFlags_ & ir::ScriptFunctionFlags::THROWS) != 0; } + bool IsRethrowing() const + { + return (funcFlags_ & ir::ScriptFunctionFlags::RETHROWS) != 0; + } + void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/ets2panda/ir/ts/tsAsExpression.h b/ets2panda/ir/ts/tsAsExpression.h index ba4903adaba877e18f6e07985238cfdfcfec036e..1fa6865140ceb5173f2f76915cedee3e3195b2a1 100644 --- a/ets2panda/ir/ts/tsAsExpression.h +++ b/ets2panda/ir/ts/tsAsExpression.h @@ -49,6 +49,11 @@ public: return isConst_; } + void SetUncheckedCast(bool isUncheckedCast) + { + isUncheckedCast_ = isUncheckedCast; + } + void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/ets2panda/test/compiler/ets/FunctionType1-expected.txt b/ets2panda/test/compiler/ets/FunctionType1-expected.txt index eb64020f40e49445ed82f79f28fa02782d538428..a62c8dd85d60ae17e7e06f6baa860ffc9336f53d 100644 --- a/ets2panda/test/compiler/ets/FunctionType1-expected.txt +++ b/ets2panda/test/compiler/ets/FunctionType1-expected.txt @@ -1001,4 +1001,4 @@ } } } -TypeError: Type '(a: int, b: int) => int' cannot be assigned to type '(a: int, b: int) => void' [FunctionType1.ets:24:12] +TypeError: Type '(a: int, b: int) => int' cannot be assigned to type '(p1: Int, p2: Int) => void' [FunctionType1.ets:24:12] diff --git a/ets2panda/test/compiler/ets/FunctionType3-expected.txt b/ets2panda/test/compiler/ets/FunctionType3-expected.txt index bbb4c6e27b15eea2054e80a1da9798db1abe9305..0d0d88e229b078e339a18c8a16becd16b3ed2448 100644 --- a/ets2panda/test/compiler/ets/FunctionType3-expected.txt +++ b/ets2panda/test/compiler/ets/FunctionType3-expected.txt @@ -809,4 +809,4 @@ } } } -TypeError: Type 'string' is not compatible with type 'int' at index 2 [FunctionType3.ets:23:16] +TypeError: Type 'string' is not compatible with type 'Int' at index 2 [FunctionType3.ets:23:16] diff --git a/ets2panda/test/compiler/ets/etsObjectToString4-expected.txt b/ets2panda/test/compiler/ets/etsObjectToString4-expected.txt index a92c60328361986dbfda8e79c83c01c8505f41a3..37dcab16aececbdb7b0660c38bc52df306ee85f5 100644 --- a/ets2panda/test/compiler/ets/etsObjectToString4-expected.txt +++ b/ets2panda/test/compiler/ets/etsObjectToString4-expected.txt @@ -465,4 +465,4 @@ } } } -TypeError: Type 'int' cannot be assigned to type '() => int' [etsObjectToString4.ets:18:29] +TypeError: Type 'int' cannot be assigned to type '() => Int' [etsObjectToString4.ets:18:29] diff --git a/ets2panda/test/compiler/ets/etsObjectToString5-expected.txt b/ets2panda/test/compiler/ets/etsObjectToString5-expected.txt index c96da27d618f81a70d048be77af960f521cdfca5..dbdd0fed4e0b5ac0e13c4f998d7ee93908e232b9 100644 --- a/ets2panda/test/compiler/ets/etsObjectToString5-expected.txt +++ b/ets2panda/test/compiler/ets/etsObjectToString5-expected.txt @@ -845,4 +845,4 @@ } } } -TypeError: Type '(y: A) => A|null' cannot be assigned to type '(y: A) => A|null' [etsObjectToString5.ets:18:42] +TypeError: Type '(y: A) => A|null' cannot be assigned to type '(p1: A) => A|null' [etsObjectToString5.ets:18:42] diff --git a/ets2panda/test/compiler/ets/function_subtyping_1-expected.txt b/ets2panda/test/compiler/ets/function_subtyping_1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..ca68775f5e7c4bc5c7f56237ce0df6d0a6b5102e --- /dev/null +++ b/ets2panda/test/compiler/ets/function_subtyping_1-expected.txt @@ -0,0 +1,997 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "implements": [], + "body": [ + { + "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": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 18 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 27 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 27 + }, + "end": { + "line": 20, + "column": 32 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 54 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 54 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 20, + "column": 48 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 41 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 39 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "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": 21, + "column": 2 + } + } +} diff --git a/ets2panda/test/compiler/ets/function_subtyping_1.ets b/ets2panda/test/compiler/ets/function_subtyping_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..0b2ffc867e56034fb79f90e76dc9f53a784492f0 --- /dev/null +++ b/ets2panda/test/compiler/ets/function_subtyping_1.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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 {} +class B extends A {} + +function main(): void { + let x: (p: B) => A = (p: A): B => { return new B() } +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/function_subtyping_2-expected.txt b/ets2panda/test/compiler/ets/function_subtyping_2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..b49902e0360b9b56bf1c02ddee4587169b8038a5 --- /dev/null +++ b/ets2panda/test/compiler/ets/function_subtyping_2-expected.txt @@ -0,0 +1,998 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "implements": [], + "body": [ + { + "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": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 18 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 27 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 27 + }, + "end": { + "line": 20, + "column": 32 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 54 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 54 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 20, + "column": 48 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 41 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 39 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "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": 21, + "column": 2 + } + } +} +TypeError: Type '(p: A) => A' cannot be assigned to type '(p1: B) => B' [function_subtyping_2.ets:20:26] diff --git a/ets2panda/test/compiler/ets/function_subtyping_2.ets b/ets2panda/test/compiler/ets/function_subtyping_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..64860a92b84090397682ef3b294ceaf8f3238e5e --- /dev/null +++ b/ets2panda/test/compiler/ets/function_subtyping_2.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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 {} +class B extends A {} + +function main(): void { + let x: (p: B) => B = (p: A): A => { return new B() } +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/function_subtyping_3-expected.txt b/ets2panda/test/compiler/ets/function_subtyping_3-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..55e50a03bc5ecb3b7575a869ff4157abd02441b0 --- /dev/null +++ b/ets2panda/test/compiler/ets/function_subtyping_3-expected.txt @@ -0,0 +1,998 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "implements": [], + "body": [ + { + "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": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 18 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 27 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 27 + }, + "end": { + "line": 20, + "column": 32 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 54 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 52 + }, + "end": { + "line": 20, + "column": 54 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 20, + "column": 48 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 41 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 39 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 57 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "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": 21, + "column": 2 + } + } +} +TypeError: Type '(p: B) => B' cannot be assigned to type '(p1: A) => A' [function_subtyping_3.ets:20:26] diff --git a/ets2panda/test/compiler/ets/function_subtyping_3.ets b/ets2panda/test/compiler/ets/function_subtyping_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e57a855ae937b56c005189c6c52c898c43b5c5b --- /dev/null +++ b/ets2panda/test/compiler/ets/function_subtyping_3.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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 {} +class B extends A {} + +function main(): void { + let x: (p: A) => A = (p: B): B => { return new B() } +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/generic_variance_1-expected.txt b/ets2panda/test/compiler/ets/generic_variance_1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..abef87ab4c4cf75d73e08363d4d783627af2c92e --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_1-expected.txt @@ -0,0 +1,1973 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "implements": [], + "body": [ + { + "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": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "in": true, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 16 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "out": true, + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + { + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x1", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 15 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 11 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 27 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 23, + "column": 21 + }, + "end": { + "line": 24, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 24, + "column": 8 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 24, + "column": 8 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x2", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 24, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 16 + }, + "end": { + "line": 24, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 16 + }, + "end": { + "line": 24, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 16 + }, + "end": { + "line": 24, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 15 + }, + "end": { + "line": 24, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 24, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 24, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 11 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 25 + }, + "end": { + "line": 24, + "column": 27 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 28 + }, + "end": { + "line": 24, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 28 + }, + "end": { + "line": 24, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 28 + }, + "end": { + "line": 24, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 27 + }, + "end": { + "line": 24, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 25 + }, + "end": { + "line": 24, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 25 + }, + "end": { + "line": 24, + "column": 31 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 26, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 26, + "column": 8 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 26, + "column": 8 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x3", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 13 + }, + "end": { + "line": 26, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 15 + }, + "end": { + "line": 26, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 13 + }, + "end": { + "line": 26, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 13 + }, + "end": { + "line": 26, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 9 + }, + "end": { + "line": 26, + "column": 11 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 25 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 28 + }, + "end": { + "line": 26, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 28 + }, + "end": { + "line": 26, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 28 + }, + "end": { + "line": 26, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 27 + }, + "end": { + "line": 26, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 25 + }, + "end": { + "line": 26, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 25 + }, + "end": { + "line": 26, + "column": 31 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 26, + "column": 21 + }, + "end": { + "line": 27, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 9 + }, + "end": { + "line": 27, + "column": 8 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 26, + "column": 5 + }, + "end": { + "line": 27, + "column": 8 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x4", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 16 + }, + "end": { + "line": 27, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 16 + }, + "end": { + "line": 27, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 16 + }, + "end": { + "line": 27, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 15 + }, + "end": { + "line": 27, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 9 + }, + "end": { + "line": 27, + "column": 11 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 27 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 28 + }, + "end": { + "line": 27, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 28 + }, + "end": { + "line": 27, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 28 + }, + "end": { + "line": 27, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 27 + }, + "end": { + "line": 27, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 31 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 27, + "column": 21 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 9 + }, + "end": { + "line": 28, + "column": 2 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 28, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 23 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 28, + "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": 28, + "column": 2 + } + } +} diff --git a/ets2panda/test/compiler/ets/generic_variance_1.ets b/ets2panda/test/compiler/ets/generic_variance_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..dee382251f27b4b4bf54bd1301d60bd5101e1333 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_1.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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 {} +class B extends A {} + +class A1 {} +class A2 {} + +function main(): void { + let x1: A1 = new A1() + let x2: A1 = new A1() + + let x3: A2 = new A2() + let x4: A2 = new A2() +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/generic_variance_2-expected.txt b/ets2panda/test/compiler/ets/generic_variance_2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..227f565f389428b1045e0e534beb36cd377f33cd --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_2-expected.txt @@ -0,0 +1,1218 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "implements": [], + "body": [ + { + "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": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "in": true, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 16 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "out": true, + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + { + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x1", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 15 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 11 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 27 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 23, + "column": 21 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 23 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 24, + "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": 24, + "column": 2 + } + } +} +TypeError: Type 'A1' cannot be assigned to type 'A1' [generic_variance_2.ets:23:21] diff --git a/ets2panda/test/compiler/ets/generic_variance_2.ets b/ets2panda/test/compiler/ets/generic_variance_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..a3bc04b21106d940201239715b1df566b8c54390 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_2.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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 {} +class B extends A {} + +class A1 {} +class A2 {} + +function main(): void { + let x1: A1 = new A1() +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/generic_variance_3-expected.txt b/ets2panda/test/compiler/ets/generic_variance_3-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..3bb1aa6f553a968fa3737fc7131a53455a5471f3 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_3-expected.txt @@ -0,0 +1,1218 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "implements": [], + "body": [ + { + "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": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "in": true, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 16 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "out": true, + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + { + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x1", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 15 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 11 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 27 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 23, + "column": 21 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 23 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 24, + "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": 24, + "column": 2 + } + } +} +TypeError: Type 'A2' cannot be assigned to type 'A2' [generic_variance_3.ets:23:21] diff --git a/ets2panda/test/compiler/ets/generic_variance_3.ets b/ets2panda/test/compiler/ets/generic_variance_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b61cf93020ab46e12e7ff3529e19a89aeced8a0 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_3.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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 {} +class B extends A {} + +class A1 {} +class A2 {} + +function main(): void { + let x1: A2 = new A2() +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/generic_variance_4-expected.txt b/ets2panda/test/compiler/ets/generic_variance_4-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..a3be0edfd53c7b33af22adc6758d875021534c77 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_4-expected.txt @@ -0,0 +1,1178 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "in": true, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 16 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "out": true, + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + { + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x2", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 15 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 11 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 27 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 23, + "column": 21 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 23 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 24, + "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": 24, + "column": 2 + } + } +} +TypeError: Type 'A1' cannot be assigned to type 'A1' [generic_variance_4.ets:23:21] diff --git a/ets2panda/test/compiler/ets/generic_variance_4.ets b/ets2panda/test/compiler/ets/generic_variance_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..bc985183024577a560e50aa367a96c900c579be2 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_4.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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 {} +class B {} + +class A1 {} +class A2 {} + +function main(): void { + let x2: A1 = new A1() +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/generic_variance_5-expected.txt b/ets2panda/test/compiler/ets/generic_variance_5-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..07709a6558f4d84f09ff4d90575315dab782d991 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_5-expected.txt @@ -0,0 +1,1178 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "in": true, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 16 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "out": true, + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + { + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x4", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 15 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 11 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 27 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 23, + "column": 21 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 23 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 24, + "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": 24, + "column": 2 + } + } +} +TypeError: Type 'A2' cannot be assigned to type 'A2' [generic_variance_5.ets:23:21] diff --git a/ets2panda/test/compiler/ets/generic_variance_5.ets b/ets2panda/test/compiler/ets/generic_variance_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..9e351ad8f9ad8cd90c7a8bb0514f9d2122b4917c --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_variance_5.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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 {} +class B {} + +class A1 {} +class A2 {} + +function main(): void { + let x4: A2 = new A2() +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/identifierReference2-expected.txt b/ets2panda/test/compiler/ets/identifierReference2-expected.txt index c0fb2875eaa35752d68d03bccc91b4ba8fc0d2a9..100cdc5d9da37ed85518a0c2b428f0fb57b24619 100644 --- a/ets2panda/test/compiler/ets/identifierReference2-expected.txt +++ b/ets2panda/test/compiler/ets/identifierReference2-expected.txt @@ -398,4 +398,4 @@ } } } -TypeError: Type '(v: double, u: double) => double' cannot be assigned to type '(a: int, b: int) => void' [identifierReference2.ets:16:34] +TypeError: Type '(v: double, u: double) => double' cannot be assigned to type '(p1: Int, p2: Int) => void' [identifierReference2.ets:16:34] diff --git a/ets2panda/test/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentType-expected.txt b/ets2panda/test/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentType-expected.txt index a17df28bb337b0d74b04879a1bb4e4a8890a0fd9..d7fafa4654f0fea7e5ee572646ba22800f3d2d44 100644 --- a/ets2panda/test/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentType-expected.txt +++ b/ets2panda/test/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentType-expected.txt @@ -515,4 +515,4 @@ } } } -TypeError: Type '() => String' cannot be assigned to type '() => int' [lambdaExpressionWithoutBlockStatementDifferentType.ets:17:28] +TypeError: Type '() => String' cannot be assigned to type '() => Int' [lambdaExpressionWithoutBlockStatementDifferentType.ets:17:28] diff --git a/ets2panda/test/compiler/ets/lambdaFunction3-expected.txt b/ets2panda/test/compiler/ets/lambdaFunction3-expected.txt index 22b2a3c2f299f5bea005e116a3f713eede8dbe30..1e358988d23eb51fd4051bddf93911fcf3861fb8 100644 --- a/ets2panda/test/compiler/ets/lambdaFunction3-expected.txt +++ b/ets2panda/test/compiler/ets/lambdaFunction3-expected.txt @@ -642,4 +642,4 @@ } } } -TypeError: Type '(b: int) => void' cannot be assigned to type '(b: String) => void' [lambdaFunction3.ets:18:39] +TypeError: Type '(b: int) => void' cannot be assigned to type '(p1: String) => void' [lambdaFunction3.ets:18:39] diff --git a/ets2panda/test/compiler/ets/lambdaFunction5-expected.txt b/ets2panda/test/compiler/ets/lambdaFunction5-expected.txt index 5737ced2b4eaa0c3cb5614fd7a5e7a02b82a8e43..b82ab2b93218d0c24802219361d0308fec15622e 100644 --- a/ets2panda/test/compiler/ets/lambdaFunction5-expected.txt +++ b/ets2panda/test/compiler/ets/lambdaFunction5-expected.txt @@ -1705,4 +1705,4 @@ } } } -TypeError: Type 'string' is not compatible with type 'int' at index 2 [lambdaFunction5.ets:35:17] +TypeError: Type 'string' is not compatible with type 'Int' at index 2 [lambdaFunction5.ets:35:17] diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt index 545b1715cf2905525d1f37c516f466f808038e42..21e87c7c1a01ed9ce6bec01f0688ec0e8f443579 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt @@ -289,7 +289,7 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "B", + "name": "A", "decorators": [], "loc": { "start": { @@ -354,9 +354,49 @@ { "type": "ReturnStatement", "argument": { - "type": "Identifier", - "name": "a", - "decorators": [], + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 41 + }, + "end": { + "line": 22, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 41 + }, + "end": { + "line": 22, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 41 + }, + "end": { + "line": 22, + "column": 44 + } + } + }, + "arguments": [], "loc": { "start": { "line": 22, @@ -364,7 +404,7 @@ }, "end": { "line": 22, - "column": 38 + "column": 44 } } }, @@ -375,7 +415,7 @@ }, "end": { "line": 22, - "column": 38 + "column": 44 } } } @@ -387,7 +427,7 @@ }, "end": { "line": 22, - "column": 39 + "column": 44 } } }, @@ -398,7 +438,7 @@ }, "end": { "line": 22, - "column": 39 + "column": 44 } } }, @@ -409,7 +449,7 @@ }, "end": { "line": 22, - "column": 39 + "column": 44 } } }, @@ -432,33 +472,33 @@ "loc": { "start": { "line": 22, - "column": 48 + "column": 53 }, "end": { "line": 22, - "column": 49 + "column": 54 } } }, "loc": { "start": { "line": 22, - "column": 48 + "column": 53 }, "end": { "line": 22, - "column": 50 + "column": 55 } } }, "loc": { "start": { "line": 22, - "column": 48 + "column": 53 }, "end": { "line": 22, - "column": 50 + "column": 55 } } }, @@ -466,22 +506,22 @@ "loc": { "start": { "line": 22, - "column": 44 + "column": 49 }, "end": { "line": 22, - "column": 50 + "column": 55 } } }, "loc": { "start": { "line": 22, - "column": 44 + "column": 49 }, "end": { "line": 22, - "column": 50 + "column": 55 } } } @@ -497,18 +537,18 @@ "loc": { "start": { "line": 22, - "column": 54 + "column": 59 }, "end": { "line": 22, - "column": 55 + "column": 60 } } }, "loc": { "start": { "line": 22, - "column": 54 + "column": 59 }, "end": { "line": 23, @@ -519,7 +559,7 @@ "loc": { "start": { "line": 22, - "column": 54 + "column": 59 }, "end": { "line": 23, @@ -530,7 +570,7 @@ "loc": { "start": { "line": 22, - "column": 43 + "column": 48 }, "end": { "line": 23, @@ -545,7 +585,7 @@ }, "end": { "line": 22, - "column": 39 + "column": 44 } } }, @@ -556,7 +596,7 @@ }, "end": { "line": 22, - "column": 39 + "column": 44 } } } @@ -569,7 +609,7 @@ }, "end": { "line": 22, - "column": 39 + "column": 44 } } }, @@ -595,7 +635,7 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "A", + "name": "B", "decorators": [], "loc": { "start": { diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets index cb90f223b65492d77d5f230dba1fa2e5a2097eaf..2d5c270007400772d8aa797f644c91391f04ca04 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets @@ -19,7 +19,7 @@ class A { class B extends A { main () { - let a = (a : B) => { return a} as (a : A) => A - let expected : (a : A) => A = a + let a = (a : A) => { return new B } as (a : A) => A + let expected : (a : B) => A = a } } diff --git a/ets2panda/test/compiler/ets/methodOverrideCovariantReturnType-expected.txt b/ets2panda/test/compiler/ets/methodOverrideCovariantReturnType-expected.txt index 186fa4c37141f593fb820c8dc978c6d5a0388b67..36610c08a0f6982d1fad63bdf19f31ef144a989f 100644 --- a/ets2panda/test/compiler/ets/methodOverrideCovariantReturnType-expected.txt +++ b/ets2panda/test/compiler/ets/methodOverrideCovariantReturnType-expected.txt @@ -2084,4 +2084,3 @@ } } } -TypeError: foo(a: int): C in B cannot override foo(): A in A because overriding return type is not compatible with the other return type. [methodOverrideCovariantReturnType.ets:42:8] diff --git a/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable-expected.txt b/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable-expected.txt index 218cfffdcb33c7c392be1d8fa7840ee67f888e43..50c023906d4668b5aceccf46af2ffaef33053903 100644 --- a/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable-expected.txt +++ b/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable-expected.txt @@ -1012,4 +1012,4 @@ } } } -TypeError: Type 'A' cannot be assigned to type 'A' [n_assignGenericWithNullableTypeParamToNonNullable.ets:21:19] +TypeError: Type 'A' cannot be assigned to type 'A' [n_assignGenericWithNullableTypeParamToNonNullable.ets:20:27] diff --git a/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets b/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets index 8dab208be01f4e78883dae08af77e7f8022f906a..bbe9f2aa80e7c880b27ccd0ca7dcc9b9745f1368 100644 --- a/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets +++ b/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets @@ -17,6 +17,6 @@ class A {} class B {} function main(): void { - let abn : A = new A(); // should work: non nullable B is the subtype of nullable B + let abn : A = new A(); // should not work: non nullable B is the subtype of nullable B, but T has no variance mark let ab : A = abn; // should not work: nullable B (the type of abn) is not the subtype of non nullable B } diff --git a/ets2panda/test/compiler/ets/overload_with_generics-expected.txt b/ets2panda/test/compiler/ets/overload_with_generics-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b5703c1493afd528dc17347c6a422110916f61e --- /dev/null +++ b/ets2panda/test/compiler/ets/overload_with_generics-expected.txt @@ -0,0 +1,1209 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 22 + } + } + }, + "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": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 22 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "arg", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 32 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 32 + }, + "end": { + "line": 17, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 32 + }, + "end": { + "line": 17, + "column": 35 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 17, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 17, + "column": 35 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 37 + }, + "end": { + "line": 17, + "column": 41 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 37 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 37 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 26 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 17, + "column": 42 + }, + "end": { + "line": 17, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 44 + } + } + }, + "overloads": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "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": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "arg1", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 37 + }, + "end": { + "line": 18, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 37 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 37 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "arg2", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 47 + }, + "end": { + "line": 18, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 47 + }, + "end": { + "line": 18, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 47 + }, + "end": { + "line": 18, + "column": 50 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 41 + }, + "end": { + "line": 18, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 41 + }, + "end": { + "line": 18, + "column": 50 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 52 + }, + "end": { + "line": 18, + "column": 56 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 52 + }, + "end": { + "line": 18, + "column": 58 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 52 + }, + "end": { + "line": 18, + "column": 58 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "A1", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "A2", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 30 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 18, + "column": 57 + }, + "end": { + "line": 18, + "column": 59 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 59 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 59 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 59 + } + } + } + ], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 44 + } + } + }, + { + "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": 19, + "column": 2 + }, + "end": { + "line": 19, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 19, + "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 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10 + }, + "end": { + "line": 21, + "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": 21, + "column": 10 + }, + "end": { + "line": 21, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 21, + "column": 18 + }, + "end": { + "line": 21, + "column": 21 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 6 + } + } + }, + "property": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 7 + }, + "end": { + "line": 22, + "column": 10 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 10 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "lll", + "loc": { + "start": { + "line": 22, + "column": 11 + }, + "end": { + "line": 22, + "column": 16 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 6 + } + } + }, + "property": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 7 + }, + "end": { + "line": 23, + "column": 10 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 10 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "lll", + "loc": { + "start": { + "line": 23, + "column": 11 + }, + "end": { + "line": 23, + "column": 16 + } + } + }, + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 19 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 22 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 25, + "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": 26, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/overload_with_generics.ets b/ets2panda/test/compiler/ets/overload_with_generics.ets new file mode 100644 index 0000000000000000000000000000000000000000..b0c007e32a8c5ff832dc535cd86bee703c13e6b3 --- /dev/null +++ b/ets2panda/test/compiler/ets/overload_with_generics.ets @@ -0,0 +1,25 @@ +/** + * 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 { + public static foo(arg: A1): void {} + public static foo(arg1: A1, arg2: A2): void {} +} + +function main(): int { + A.foo("lll") + A.foo("lll", 1) + return 0 +} diff --git a/ets2panda/test/compiler/ets/override16-expected.txt b/ets2panda/test/compiler/ets/override16-expected.txt index b1fa4f9c7e759e54e7a618c444c7222a23ae0ede..cf234349f288e38c4ac38e767197a72ad85eaf39 100644 --- a/ets2panda/test/compiler/ets/override16-expected.txt +++ b/ets2panda/test/compiler/ets/override16-expected.txt @@ -735,4 +735,4 @@ } } } -TypeError: Hiding method is not return-type-substitutable for other method. [override16.ets:23:5] +TypeError: fn(): float in B cannot override fn(): int in A because overridden method is static. [override16.ets:23:5] diff --git a/ets2panda/test/parser/ets/function_implicit_return_type2-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type2-expected.txt index b9803f021ffc4714d36a4bbeaddbe716a29f4bc7..b6a70f9b2ed7e2cdf74a7afe6b606d23ab8f9970 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type2-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type2-expected.txt @@ -316,4 +316,4 @@ } } } -TypeError: Type '() => void' cannot be assigned to type '(i: int) => int' [function_implicit_return_type2.ets:17:27] +TypeError: Type '() => void' cannot be assigned to type '(p1: Int) => Int' [function_implicit_return_type2.ets:17:27] diff --git a/ets2panda/test/parser/ets/function_implicit_return_type3-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type3-expected.txt index 86af963d88c0da2bfb2a9312765e549b3382fb33..ef11ad3a7588f5e3f482653456dfb26ed32c6505 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type3-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type3-expected.txt @@ -465,4 +465,4 @@ } } } -TypeError: Type '(i: int) => void' cannot be assigned to type '(i: int) => int' [function_implicit_return_type3.ets:18:27] +TypeError: Type '(i: int) => void' cannot be assigned to type '(p1: Int) => Int' [function_implicit_return_type3.ets:18:27] diff --git a/ets2panda/test/parser/ets/interface-expected.txt b/ets2panda/test/parser/ets/interface-expected.txt index a84f38f68d4849754da0362d7b5a9cd6bd526622..13e389abc2acaec44366f508159f099715f13716 100644 --- a/ets2panda/test/parser/ets/interface-expected.txt +++ b/ets2panda/test/parser/ets/interface-expected.txt @@ -156,7 +156,7 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "Function", + "name": "FunctioN", "decorators": [], "loc": { "start": { @@ -375,4 +375,4 @@ } } } -SyntaxError: Cannot find type 'Function'. [interface.ets:17:39] +SyntaxError: Cannot find type 'FunctioN'. [interface.ets:17:39] diff --git a/ets2panda/test/parser/ets/interface.ets b/ets2panda/test/parser/ets/interface.ets index e43e384d53b1f2491e8c060ef52b7fe76e876e35..80534bb52cecbe31aa07ffe20355ce2d8675a65c 100644 --- a/ets2panda/test/parser/ets/interface.ets +++ b/ets2panda/test/parser/ets/interface.ets @@ -14,5 +14,5 @@ */ -interface G {} +interface G {} diff --git a/ets2panda/test/parser/ets/lambda-type-inference-neg-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-neg-expected.txt index b814441ff1eb97ccfdb53687762b638838cc1e19..4ac2df4d2f11ea619c64a304f402819012fa2efe 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-neg-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-neg-expected.txt @@ -928,4 +928,4 @@ } } } -TypeError: Reference to foo is ambiguous [lambda-type-inference-neg.ets:23:5] +TypeError: Function with this assembly signature already declared. [lambda-type-inference-neg.ets:19:1] diff --git a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-1-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-1-expected.txt index 5c3f1759fa7bb05c48bd7259abfb0a31864cbf07..898613c8c74f3a5b76c2dd433a9588aa22013ac9 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-1-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-1-expected.txt @@ -1963,4 +1963,4 @@ } } } -TypeError: Reference to foo is ambiguous [lambda-type-inference-overloaded-1.ets:32:5] +TypeError: Function with this assembly signature already declared. [lambda-type-inference-overloaded-1.ets:20:1] diff --git a/ets2panda/test/runtime/ets/conversion-char-boolean.ets b/ets2panda/test/runtime/ets/conversion-char-boolean.ets index 76f9ea8e29cc817dac783009e3bda81123d9b699..2b8d23bc6885254a8d991ef612f7438ed9668492 100644 --- a/ets2panda/test/runtime/ets/conversion-char-boolean.ets +++ b/ets2panda/test/runtime/ets/conversion-char-boolean.ets @@ -20,7 +20,7 @@ function check(): Boolean { function main(): void { let x: Boolean = false; - assert (x || check()); + assert (!x || check()); let y: Char = c'a'; assert (y != c'b'); diff --git a/ets2panda/test/runtime/ets/unboxingBooleanConversion.ets b/ets2panda/test/runtime/ets/unboxingBooleanConversion.ets index 7fb437eeda604faf3dfea8614bab86f2a935cf2c..8a865706f58f9213c2b361f4d287947563dee922 100644 --- a/ets2panda/test/runtime/ets/unboxingBooleanConversion.ets +++ b/ets2panda/test/runtime/ets/unboxingBooleanConversion.ets @@ -23,8 +23,9 @@ function returnRefBool(a: boolean): Boolean { function main(): void { let a: Boolean = false; + let a2: Boolean = true - let b: Boolean = a && returnTrue(); + let b: Boolean = a || a2; assert b == true let c: Boolean = returnRefBool(a || returnRefBool(returnRefBool(a))); diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index e8521c7c0b4ab6db263b0c1cd4a4363e32f60403..c12cc9299c3a9aabffb9ddaff8c9db202086395b 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -47,3 +47,12 @@ struct-init.ets struct-init2.ets struct_implements.ets top_level_03.ets + +# Union with undefined +OptionalCall.ets + +# Functional type with rest parameter +lambdaExpressionWithRestParameter.ets + +# Non-trivial cast sequence +castSequence.ets diff --git a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt index de27323be467022892a7ff1d56c6205e070690fa..803f9a2c5e09b17577ef15e31ae739395148efe6 100644 --- a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt @@ -11,3 +11,17 @@ parser/ets/import_tests/modules/struct_module.ets parser/ets/import_tests/check_exported_default_struct.ets parser/ets/import_tests/modules/struct_default_module.ets parser/ets/import_tests/check_exported_struct.ets + +# Throwing function types are not yet supported +parser/ets/lambdaThrowsRethrows.ets +parser/ets/variable_throw_function_1.ets +compiler/ets/rethrowingCheck5.ets +compiler/ets/rethrowingConstructorCheck1.ets +compiler/ets/rethrowingConstructorCheck2.ets +compiler/ets/rethrowingConstructorCheck3.ets +compiler/ets/rethrowingFunctionCheck1.ets +compiler/ets/rethrowingFunctionCheck2.ets +compiler/ets/rethrowingFunctionCheck3.ets +compiler/ets/rethrowingMethodCheck1.ets +compiler/ets/rethrowingMethodCheck2.ets +compiler/ets/rethrowingMethodCheck3.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..f6b8c9975e50857c132894302bfc84ac700052b9 100644 --- a/ets2panda/test/test-lists/parser/parser-js-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-js-ignored.txt @@ -71,10 +71,9 @@ parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body_capture_v compiler/ets/override13.ets # 15095 -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 +# Throwing function types +compiler/ets/throwingFunctionType2.ets +compiler/ets/throwingFunctionAsParameter2.ets diff --git a/ets2panda/util/declgenEts2Ts.cpp b/ets2panda/util/declgenEts2Ts.cpp index 89cb7e1e34359a11593b62fd4faaffeec4f988e0..8e4d7c9c12af43a5d643ac99543aa8ba73554f91 100644 --- a/ets2panda/util/declgenEts2Ts.cpp +++ b/ets2panda/util/declgenEts2Ts.cpp @@ -295,7 +295,8 @@ void TSDeclGen::GenEnumType(const checker::ETSEnumType *enumType) void TSDeclGen::GenObjectType(const checker::ETSObjectType *objectType) { if (objectType->HasObjectFlag(checker::ETSObjectFlags::FUNCTIONAL)) { - const auto *invoke = objectType->GetOwnProperty("invoke"); + const auto *invoke = objectType->GetOwnProperty( + checker::FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME); ASSERT(invoke && invoke->TsType() && invoke->TsType()->IsETSFunctionType()); GenType(invoke->TsType()); return; diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 06d08f355360f8048f07c6523e8c017e54484f05..1e6c232d0147c67bc69612645ecce22d0a107fbd 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -400,8 +400,9 @@ void ETSBinder::BuildLambdaObject(ir::AstNode *refNode, ir::ClassDefinition *lam auto boundCtx = BoundContext(GetGlobalRecordTable(), lambdaObject); const auto &lambdaBody = lambdaObject->Body(); + AddLambdaFunctionThisParam(lambdaBody[lambdaBody.size() - 3U]->AsMethodDefinition()->Function()); AddLambdaFunctionThisParam(lambdaBody[lambdaBody.size() - 2U]->AsMethodDefinition()->Function()); - AddLambdaFunctionThisParam(lambdaBody[lambdaBody.size() - 1]->AsMethodDefinition()->Function()); + AddLambdaFunctionThisParam(lambdaBody[lambdaBody.size() - 1U]->AsMethodDefinition()->Function()); LambdaObjects().insert({refNode, {lambdaObject, signature}}); } @@ -876,16 +877,6 @@ void ETSBinder::FormLambdaName(util::UString &name, const util::StringView &sign name.Append(replaced); } -void ETSBinder::FormFunctionalInterfaceName(util::UString &name, const util::StringView &signature) -{ - auto replaced = std::string(signature.Utf8()); - std::replace(replaced.begin(), replaced.end(), '.', '-'); - std::replace(replaced.begin(), replaced.end(), ':', '-'); - std::replace(replaced.begin(), replaced.end(), ';', '-'); - replaced.append(std::to_string(0)); - name.Append(replaced); -} - void ETSBinder::BuildLambdaObjectName(const ir::AstNode *refNode) { auto found = lambdaObjects_.find(refNode); @@ -913,51 +904,17 @@ void ETSBinder::BuildLambdaObjectName(const ir::AstNode *refNode) lambdaObject->SetAssemblerName(lambdaClass->Ident()->Name()); const auto &lambdaBody = lambdaClass->Body(); - auto *ctorFunc = lambdaBody[lambdaBody.size() - 2]->AsMethodDefinition()->Function(); + auto *ctorFunc = lambdaBody[lambdaBody.size() - 3U]->AsMethodDefinition()->Function(); auto *ctorFuncScope = ctorFunc->Scope(); ctorFuncScope->BindName(lambdaClass->Ident()->Name()); - auto *invokeFunc = lambdaBody[lambdaBody.size() - 1]->AsMethodDefinition()->Function(); - auto *invokeFuncScope = invokeFunc->Scope(); - invokeFuncScope->BindName(lambdaClass->Ident()->Name()); -} - -void ETSBinder::BuildFunctionalInterfaceName(ir::ETSFunctionType *funcType) -{ - auto *functionalInterface = funcType->FunctionalInterface(); - auto *invokeFunc = functionalInterface->Body()->Body()[0]->AsMethodDefinition()->Function(); - util::UString functionalInterfaceName(functionalInterface->Id()->Name(), Allocator()); - std::stringstream ss; - invokeFunc->Signature()->ToAssemblerType(GetCompilerContext(), ss); - std::string signatureString = ss.str(); - util::StringView signatureName(signatureString); - FormFunctionalInterfaceName(functionalInterfaceName, signatureName); - functionalInterface->Id()->SetName(functionalInterfaceName.View()); - util::UString internalName(Program()->GetPackageName(), Allocator()); - if (!(internalName.View().Empty())) { - internalName.Append(compiler::Signatures::METHOD_SEPARATOR); - } - internalName.Append(functionalInterface->Id()->Name()); - functionalInterface->SetInternalName(internalName.View()); - - checker::ETSObjectType *functionalInterfaceType = functionalInterface->TsType()->AsETSObjectType(); - functionalInterfaceType->SetName(functionalInterface->Id()->Name()); - functionalInterfaceType->SetAssemblerName(internalName.View()); + auto *invoke0Func = lambdaBody[lambdaBody.size() - 2U]->AsMethodDefinition()->Function(); + auto *invoke0FuncScope = invoke0Func->Scope(); + invoke0FuncScope->BindName(lambdaClass->Ident()->Name()); + auto *invokeFunc = lambdaBody[lambdaBody.size() - 1U]->AsMethodDefinition()->Function(); auto *invokeFuncScope = invokeFunc->Scope(); - invokeFuncScope->BindName(functionalInterface->Id()->Name()); - - util::UString invokeInternalName(Program()->GetPackageName(), Allocator()); - if (!(invokeInternalName.View().Empty())) { - invokeInternalName.Append(compiler::Signatures::METHOD_SEPARATOR); - } - invokeInternalName.Append(invokeFuncScope->Name()); - invokeInternalName.Append(compiler::Signatures::METHOD_SEPARATOR); - invokeInternalName.Append(invokeFunc->Id()->Name()); - std::stringstream invokeSignatureSs; - invokeFunc->Signature()->ToAssemblerType(GetCompilerContext(), invokeSignatureSs); - invokeInternalName.Append(invokeSignatureSs.str()); - invokeFuncScope->BindInternalName(invokeInternalName.View()); + invokeFuncScope->BindName(lambdaClass->Ident()->Name()); } void ETSBinder::InitImplicitThisParam() diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index edd27f9a43a6b9cd3905d994d94ac3fbaf527937..0f7057727922ed23bafc385918c95c2e7a5d43a2 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -158,8 +158,6 @@ public: void AddInvokeFunctionThisParam(ir::ScriptFunction *func); void BuildLambdaObjectName(const ir::AstNode *refNode); void FormLambdaName(util::UString &name, const util::StringView &signature); - void FormFunctionalInterfaceName(util::UString &name, const util::StringView &signature); - void BuildFunctionalInterfaceName(ir::ETSFunctionType *funcType); void SetDefaultImports(ArenaVector defaultImports) {