From c52f5e985331afa332f32a647dbf254931ee0c05 Mon Sep 17 00:00:00 2001 From: Konstantin Baladurin Date: Tue, 7 Nov 2023 14:09:27 +0300 Subject: [PATCH] Support lambdas subtyping Change-Id: I6d5fcbcd395ac35ad121da684046e6d29f9266b0 Signed-off-by: Konstantin Baladurin --- ets2panda/checker/ETSchecker.cpp | 67 +- ets2panda/checker/ETSchecker.h | 31 +- ets2panda/checker/ets/function.cpp | 338 ++- ets2panda/checker/ets/helpers.cpp | 23 + ets2panda/checker/ets/object.cpp | 8 +- ets2panda/checker/ets/typeRelationContext.cpp | 3 +- .../checker/types/ets/etsFunctionType.cpp | 11 +- ets2panda/checker/types/ets/etsObjectType.cpp | 154 +- ets2panda/checker/types/ets/etsObjectType.h | 31 +- ets2panda/checker/types/globalTypesHolder.cpp | 17 + ets2panda/checker/types/globalTypesHolder.h | 22 + ets2panda/checker/types/signature.h | 2 + ets2panda/compiler/core/ETSGen.cpp | 34 +- ets2panda/compiler/core/ETSGen.h | 18 +- ets2panda/compiler/scripts/signatures.yaml | 54 + ets2panda/ir/ets/etsFunctionType.cpp | 86 +- ets2panda/ir/ets/etsFunctionType.h | 5 + ets2panda/ir/expressions/callExpression.cpp | 79 +- ets2panda/ir/expressions/callExpression.h | 3 +- ets2panda/ir/ts/tsAsExpression.h | 5 + .../ets/function_subtyping_1-expected.txt | 997 +++++++++ .../compiler/ets/function_subtyping_1.ets | 21 + .../ets/function_subtyping_2-expected.txt | 998 +++++++++ .../compiler/ets/function_subtyping_2.ets | 21 + .../ets/function_subtyping_3-expected.txt | 998 +++++++++ .../compiler/ets/function_subtyping_3.ets | 21 + .../ets/generic_variance_1-expected.txt | 1973 +++++++++++++++++ .../test/compiler/ets/generic_variance_1.ets | 28 + .../ets/generic_variance_2-expected.txt | 1218 ++++++++++ .../test/compiler/ets/generic_variance_2.ets | 24 + .../ets/generic_variance_3-expected.txt | 1218 ++++++++++ .../test/compiler/ets/generic_variance_3.ets | 24 + .../ets/generic_variance_4-expected.txt | 1178 ++++++++++ .../test/compiler/ets/generic_variance_4.ets | 24 + .../ets/generic_variance_5-expected.txt | 1178 ++++++++++ .../test/compiler/ets/generic_variance_5.ets | 24 + .../test/parser/ets/interface-expected.txt | 4 +- ets2panda/test/parser/ets/interface.ets | 2 +- .../lambda-type-inference-neg-expected.txt | 2 +- ...a-type-inference-overloaded-1-expected.txt | 2 +- ets2panda/varbinder/ETSBinder.cpp | 57 +- ets2panda/varbinder/ETSBinder.h | 2 - 42 files changed, 10717 insertions(+), 288 deletions(-) create mode 100644 ets2panda/test/compiler/ets/function_subtyping_1-expected.txt create mode 100644 ets2panda/test/compiler/ets/function_subtyping_1.ets create mode 100644 ets2panda/test/compiler/ets/function_subtyping_2-expected.txt create mode 100644 ets2panda/test/compiler/ets/function_subtyping_2.ets create mode 100644 ets2panda/test/compiler/ets/function_subtyping_3-expected.txt create mode 100644 ets2panda/test/compiler/ets/function_subtyping_3.ets create mode 100644 ets2panda/test/compiler/ets/generic_variance_1-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_variance_1.ets create mode 100644 ets2panda/test/compiler/ets/generic_variance_2-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_variance_2.ets create mode 100644 ets2panda/test/compiler/ets/generic_variance_3-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_variance_3.ets create mode 100644 ets2panda/test/compiler/ets/generic_variance_4-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_variance_4.ets create mode 100644 ets2panda/test/compiler/ets/generic_variance_5-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_variance_5.ets diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 4d5cfde2fe..719c3cb830 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -40,15 +40,60 @@ void ETSChecker::InitializeBuiltins(varbinder::ETSBinder *varbinder) auto init_builtin = [var_map](ETSChecker *checker, std::string_view signature) -> util::StringView { const auto iterator = var_map.find(signature); ASSERT(iterator != var_map.end()); - checker->GetGlobalTypesHolder()->InitializeBuiltin( - iterator->first, - checker->BuildClassProperties(iterator->second->Declaration()->Node()->AsClassDefinition())); + auto *var = iterator->second; + Type *type {nullptr}; + if (var->Declaration()->Node()->IsClassDefinition()) { + type = checker->BuildClassProperties(var->Declaration()->Node()->AsClassDefinition()); + } else { + ASSERT(var->Declaration()->Node()->IsTSInterfaceDeclaration()); + type = checker->BuildInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); + } + checker->GetGlobalTypesHolder()->InitializeBuiltin(iterator->first, type); return iterator->first; }; auto const object_name = init_builtin(this, compiler::Signatures::BUILTIN_OBJECT_CLASS); auto const void_name = init_builtin(this, compiler::Signatures::BUILTIN_VOID_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_BOOLEAN_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_CHAR_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_BYTE_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_SHORT_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_INT_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_LONG_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FLOAT_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_DOUBLE_CLASS); + + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION0_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION1_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION2_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION3_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION4_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION5_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION6_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION7_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION8_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION9_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION10_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION11_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION12_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION13_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION14_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION15_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTION16_CLASS); + init_builtin(this, compiler::Signatures::BUILTIN_FUNCTIONN_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(); + type->AddObjectFlag(ETSObjectFlags::FUNCTIONAL); + auto *invoke = type->GetOwnProperty("invoke0"); + auto *invoke_type = invoke->TsType()->AsETSFunctionType(); + ASSERT(invoke_type->CallSignatures().size() == 1); + auto *signature = invoke_type->CallSignatures()[0]; + signature->AddSignatureFlag(SignatureFlags::FUNCTIONAL_INTERFACE_SIGNATURE); + } + for (const auto &[name, var] : var_map) { if (name == object_name || name == void_name) { continue; @@ -150,9 +195,10 @@ Type *ETSChecker::CheckTypeCached(ir::Expression *expr) return expr->TsType(); } -ETSObjectType *ETSChecker::AsETSObjectType(Type *(GlobalTypesHolder::*type_functor)()) const +template +ETSObjectType *ETSChecker::AsETSObjectType(Type *(GlobalTypesHolder::*type_functor)(Args...), Args... args) const { - auto *ret = (GetGlobalTypesHolder()->*type_functor)(); + auto *ret = (GetGlobalTypesHolder()->*type_functor)(args...); return ret != nullptr ? ret->AsETSObjectType() : nullptr; } @@ -271,6 +317,17 @@ 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 static_cast(checker::GlobalTypeId::ETS_FUNCTIONN_CLASS) - + static_cast(checker::GlobalTypeId::ETS_FUNCTION0_CLASS); +} + 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 756489ee87..62b605922f 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -60,6 +60,7 @@ using ArrayMap = ArenaUnorderedMap; using GlobalArraySignatureMap = ArenaUnorderedMap; using DynamicCallIntrinsicsMap = ArenaUnorderedMap>; using DynamicLambdaObjectSignatureMap = ArenaUnorderedMap; +using FunctionalInterfaceMap = ArenaUnorderedMap; class ETSChecker final : public Checker { public: @@ -72,7 +73,8 @@ public: cached_computed_abstracts_(Allocator()->Adapter()), dynamic_call_intrinsics_(Allocator()->Adapter()), dynamic_new_intrinsics_(Allocator()->Adapter()), - dynamic_lambda_signature_cache_(Allocator()->Adapter()) + dynamic_lambda_signature_cache_(Allocator()->Adapter()), + functional_interface_cache_(Allocator()->Adapter()) { } @@ -112,6 +114,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; @@ -342,7 +347,7 @@ public: ArenaVector &properties); std::tuple CreateLambdaCtorImplicitParam( ArenaVector ¶ms, const lexer::SourceRange &pos, bool is_static_reference); - ir::MethodDefinition *CreateLambdaInvokeProto(); + ir::MethodDefinition *CreateLambdaInvokeProto(util::StringView invoke_name); void CreateLambdaFuncDecl(ir::MethodDefinition *func, varbinder::LocalScope *scope); void ResolveProxyMethod(ir::MethodDefinition *proxy_method, ir::ArrowFunctionExpression *lambda); void ResolveLambdaObject(ir::ClassDefinition *lambda_object, Signature *signature, @@ -351,18 +356,18 @@ public: ir::ArrowFunctionExpression *lambda, ir::MethodDefinition *proxy_method, bool save_this); void ResolveLambdaObjectCtor(ir::ClassDefinition *lambda_object, bool is_static_reference); void ResolveLambdaObjectCtor(ir::ClassDefinition *lambda_object); - void ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, Signature *signature_ref); + void ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, Signature *signature_ref, bool iface_override); void ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, ir::ArrowFunctionExpression *lambda, - ir::MethodDefinition *proxy_method, bool is_static); - ir::Statement *ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambda_object, Signature *signature_ref); + ir::MethodDefinition *proxy_method, bool is_static, bool iface_override); + ir::Statement *ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambda_object, Signature *signature_ref, + bool iface_override); ir::Statement *ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambda_object, - ir::MethodDefinition *proxy_method, bool is_static); - void CreateFunctionalInterfaceForFunctionType(ir::ETSFunctionType *func_type); - ir::MethodDefinition *CreateInvokeFunction(ir::ETSFunctionType *func_type); + ir::ArrowFunctionExpression *lambda, + ir::MethodDefinition *proxy_method, bool is_static, + bool iface_override); void CheckCapturedVariables(); void CheckCapturedVariableInSubnodes(ir::AstNode *node, varbinder::Variable *var); void CheckCapturedVariable(ir::AstNode *node, varbinder::Variable *var); - void BuildFunctionalInterfaceName(ir::ETSFunctionType *func_type); void CreateAsyncProxyMethods(ir::ClassDefinition *class_def); ir::MethodDefinition *CreateAsyncImplMethod(ir::MethodDefinition *async_method, ir::ClassDefinition *class_def); ir::MethodDefinition *CreateAsyncProxy(ir::MethodDefinition *async_method, ir::ClassDefinition *class_def, @@ -475,6 +480,7 @@ public: ETSObjectType *GetRelevantArgumentedTypeFromChild(ETSObjectType *child, ETSObjectType *target); util::StringView GetHashFromTypeArguments(const ArenaVector &type_arg_types); util::StringView GetHashFromSubstitution(const Substitution *substitution); + util::StringView GetHashFromFunctionType(ir::ETSFunctionType *type); ETSObjectType *GetOriginalBaseType(Type *object); Type *GetTypeFromTypeAnnotation(ir::TypeNode *type_annotation); void AddUndefinedParamsForDefaultParams(const Signature *signature, @@ -536,6 +542,9 @@ public: return ret; } + ETSObjectType *GetFunctionalInterface(ir::ETSFunctionType *type); + void CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectType *iface_type); + private: using ClassBuilder = std::function *)>; using ClassInitializerBuilder = std::function *, @@ -594,7 +603,8 @@ private: template typename TargetType::UType GetOperand(Type *type); - ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*type_functor)()) const; + template + ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*type_functor)(Args...), Args... args) const; // Trailing lambda void MoveTrailingBlockToEnclosingBlockStatement(ir::CallExpression *call_expr); @@ -611,6 +621,7 @@ private: DynamicCallIntrinsicsMap dynamic_call_intrinsics_; DynamicCallIntrinsicsMap dynamic_new_intrinsics_; DynamicLambdaObjectSignatureMap dynamic_lambda_signature_cache_; + FunctionalInterfaceMap functional_interface_cache_; std::recursive_mutex mtx_; }; diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 7e6538ad77..a2153eefd7 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" @@ -1120,81 +1121,6 @@ void ETSChecker::CheckCapturedVariables() } } -void ETSChecker::BuildFunctionalInterfaceName(ir::ETSFunctionType *func_type) -{ - VarBinder()->AsETSBinder()->BuildFunctionalInterfaceName(func_type); -} - -void ETSChecker::CreateFunctionalInterfaceForFunctionType(ir::ETSFunctionType *func_type) -{ - auto *ident_node = Allocator()->New(util::StringView("FunctionalInterface"), Allocator()); - - auto interface_ctx = varbinder::LexicalScope(VarBinder()); - auto *interface_scope = interface_ctx.GetScope(); - - ArenaVector members(Allocator()->Adapter()); - ir::MethodDefinition *invoke_func = CreateInvokeFunction(func_type); - members.push_back(invoke_func); - - auto method_ctx = - varbinder::LexicalScope::Enter(VarBinder(), interface_scope->InstanceMethodScope()); - auto [_, var] = VarBinder()->NewVarDecl(invoke_func->Start(), Allocator(), - invoke_func->Id()->Name(), invoke_func); - (void)_; - var->AddFlag(varbinder::VariableFlags::METHOD); - invoke_func->Function()->Id()->SetVariable(var); - - if (func_type->IsThrowing()) { - invoke_func->Function()->AddFlag(ir::ScriptFunctionFlags::THROWS); - } - - auto *body = Allocator()->New(std::move(members)); - - ArenaVector extends(Allocator()->Adapter()); - auto *interface_decl = - Allocator()->New(Allocator(), interface_scope, ident_node, nullptr, body, - std::move(extends), false, Language(Language::Id::ETS)); - interface_decl->AddModifier(ir::ModifierFlags::FUNCTIONAL); - func_type->SetFunctionalInterface(interface_decl); - invoke_func->SetParent(interface_decl); - - VarBinder()->AsETSBinder()->BuildFunctionType(func_type); -} - -ir::MethodDefinition *ETSChecker::CreateInvokeFunction(ir::ETSFunctionType *func_type) -{ - auto *ident_node = Allocator()->New(util::StringView("invoke"), Allocator()); - - ArenaVector params(Allocator()->Adapter()); - auto *func_param_scope = CopyParams(func_type->Params(), params); - - auto param_ctx = - varbinder::LexicalScope::Enter(VarBinder(), func_param_scope, false); - auto function_ctx = varbinder::LexicalScope(VarBinder()); - auto *function_scope = function_ctx.GetScope(); - function_scope->BindParamScope(func_param_scope); - func_param_scope->BindFunctionScope(function_scope); - - ir::ModifierFlags flags = ir::ModifierFlags::ABSTRACT | ir::ModifierFlags::PUBLIC; - auto *func = Allocator()->New(function_scope, std::move(params), nullptr, nullptr, - func_type->ReturnType(), ir::ScriptFunctionFlags::METHOD, flags, - false, Language(Language::Id::ETS)); - - function_scope->BindNode(func); - func_param_scope->BindNode(func); - - auto *func_expr = Allocator()->New(func); - func->SetIdent(ident_node); - - auto *method = Allocator()->New(ir::MethodDefinitionKind::METHOD, ident_node, func_expr, - flags, Allocator(), false); - - func_expr->SetParent(method); - func->SetParent(func_expr); - - return method; -} - // Lambda creation for Lambda expressions void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpression *lambda, @@ -1241,16 +1167,19 @@ 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 *invoke_func = CreateLambdaInvokeProto(); + auto *invoke0_func = CreateLambdaInvokeProto("invoke0"); + + auto *invoke_func = CreateLambdaInvokeProto("invoke"); + properties.push_back(invoke0_func); properties.push_back(invoke_func); // Create the declarations for the synthetic constructor and invoke method CreateLambdaFuncDecl(ctor, class_scope->StaticMethodScope()); + CreateLambdaFuncDecl(invoke0_func, class_scope->InstanceMethodScope()); CreateLambdaFuncDecl(invoke_func, class_scope->InstanceMethodScope()); // Create the synthetic lambda class node - ArenaVector implements(Allocator()->Adapter()); auto *ident_node = Allocator()->New(util::StringView("LambdaObject"), Allocator()); auto *lambda_object = Allocator()->New(Allocator(), class_scope, ident_node, std::move(properties), @@ -1267,6 +1196,7 @@ void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpressio // Set the parent nodes ctor->SetParent(lambda_object); + invoke0_func->SetParent(lambda_object); invoke_func->SetParent(lambda_object); class_scope->BindNode(lambda_object); @@ -1322,14 +1252,16 @@ void ETSChecker::ResolveLambdaObject(ir::ClassDefinition *lambda_object, ETSObje ResolveLambdaObjectCtor(lambda_object); // Resolve the invoke function - ResolveLambdaObjectInvoke(lambda_object, lambda, proxy_method, !save_this); + ResolveLambdaObjectInvoke(lambda_object, lambda, proxy_method, !save_this, true); + + ResolveLambdaObjectInvoke(lambda_object, lambda, proxy_method, !save_this, false); } void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, ir::ArrowFunctionExpression *lambda, - ir::MethodDefinition *proxy_method, bool is_static) + ir::MethodDefinition *proxy_method, bool is_static, bool iface_override) { const auto &lambda_body = lambda_object->Body(); - auto *invoke_func = lambda_body[lambda_body.size() - 1]->AsMethodDefinition()->Function(); + auto *invoke_func = lambda_body[lambda_body.size() - (iface_override ? 2 : 1)]->AsMethodDefinition()->Function(); ETSObjectType *lambda_object_type = lambda_object->TsType()->AsETSObjectType(); // Set the implicit 'this' parameters type to the lambda object @@ -1341,23 +1273,42 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, i invoke_signature_info->rest_var = nullptr; // Create the parameters for the invoke function, based on the lambda function's parameters - for (auto *it : lambda->Function()->Params()) { + auto N = GlobalBuiltinFunctionTypeVariadicThreshold(); + + auto params_num = lambda->Function()->Params().size(); + + if (params_num < N || !iface_override) { + for (auto *it : lambda->Function()->Params()) { + auto param_ctx = varbinder::LexicalScope::Enter( + VarBinder(), invoke_func->Scope()->ParamScope(), false); + auto *const param = it->Clone(Allocator(), it->Parent())->AsETSParameterExpression(); + auto [_, var] = VarBinder()->AddParamDecl(param); + (void)_; + var->SetTsType(iface_override ? GlobalETSObjectType() : param->Variable()->TsType()); + param->Ident()->SetVariable(var); + invoke_func->Params().push_back(param); + invoke_signature_info->min_arg_count++; + invoke_signature_info->params.push_back(var->AsLocalVariable()); + } + } else { auto param_ctx = varbinder::LexicalScope::Enter( VarBinder(), invoke_func->Scope()->ParamScope(), false); - auto *const param = it->AsETSParameterExpression(); + auto *id = AllocNode("p", Allocator()); + auto *rest_element = AllocNode(ir::AstNodeType::REST_ELEMENT, Allocator(), id); + auto *const param = AllocNode(rest_element, nullptr); auto [_, var] = VarBinder()->AddParamDecl(param); (void)_; - var->SetTsType(param->Variable()->TsType()); + var->SetTsType(CreateETSArrayType(GlobalETSObjectType())); param->Ident()->SetVariable(var); invoke_func->Params().push_back(param); - invoke_signature_info->min_arg_count++; - invoke_signature_info->params.push_back(var->AsLocalVariable()); + invoke_signature_info->rest_var = var->AsLocalVariable(); } // Create the function type for the invoke method - auto *invoke_signature = - CreateSignature(invoke_signature_info, lambda->Function()->Signature()->ReturnType(), invoke_func); + auto *invoke_signature = CreateSignature( + invoke_signature_info, iface_override ? GlobalETSObjectType() : lambda->Function()->Signature()->ReturnType(), + invoke_func); invoke_signature->SetOwner(lambda_object_type); invoke_signature->AddSignatureFlag(checker::SignatureFlags::CALL); @@ -1370,7 +1321,7 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, i // Fill out the type information for the body of the invoke function auto *resolved_lambda_invoke_function_body = - ResolveLambdaObjectInvokeFuncBody(lambda_object, proxy_method, is_static); + ResolveLambdaObjectInvokeFuncBody(lambda_object, lambda, proxy_method, is_static, iface_override); if (invoke_func->IsAsyncFunc()) { return; } @@ -1381,7 +1332,9 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, i } ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambda_object, - ir::MethodDefinition *proxy_method, bool is_static) + ir::ArrowFunctionExpression *lambda, + ir::MethodDefinition *proxy_method, bool is_static, + bool iface_override) { const auto &lambda_body = lambda_object->Body(); auto *proxy_signature = proxy_method->Function()->Signature(); @@ -1396,7 +1349,7 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition field_ident->SetTsType(field_prop_type); } else { // Otherwise, we call the proxy method through the saved 'this' field - auto *saved_this = lambda_body[lambda_body.size() - 3]->AsClassProperty(); + auto *saved_this = lambda_body[lambda_body.size() - 4]->AsClassProperty(); auto *field_prop = saved_this->Key()->AsIdentifier()->Variable(); field_prop_type = field_prop->TsType()->AsETSObjectType(); field_ident = Allocator()->New(saved_this->Key()->AsIdentifier()->Name(), Allocator()); @@ -1413,9 +1366,9 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition callee->SetTsType(proxy_signature->OwnerVar()->TsType()); // Resolve the proxy method call arguments, first we add the captured fields to the call - auto *invoke_func = lambda_body[lambda_body.size() - 1]->AsMethodDefinition()->Function(); + auto *invoke_func = lambda_body[lambda_body.size() - (iface_override ? 2 : 1)]->AsMethodDefinition()->Function(); ArenaVector call_params(Allocator()->Adapter()); - size_t counter = is_static ? lambda_body.size() - 2 : lambda_body.size() - 3; + size_t counter = is_static ? lambda_body.size() - 3 : lambda_body.size() - 4; for (size_t i = 0; i < counter; i++) { if (lambda_body[i]->IsMethodDefinition()) { break; @@ -1429,13 +1382,50 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition call_params.push_back(param); } - // Then we add the lambda functions parameters to the call - for (auto const *const it : invoke_func->Params()) { - auto const *const param = it->AsETSParameterExpression(); + auto N = GlobalBuiltinFunctionTypeVariadicThreshold(); + + auto params_num = lambda->Function()->Params().size(); + + if (!iface_override) { + for (auto const *const it : invoke_func->Params()) { + auto const *const param = it->AsETSParameterExpression(); + auto *const param_ident = Allocator()->New(param->Ident()->Name(), Allocator()); + param_ident->SetVariable(param->Variable()); + param_ident->SetTsType(param->Variable()->TsType()); + call_params.push_back(param_ident); + } + } else if (params_num < N) { + // Then we add the lambda functions parameters to the call + auto nargs = invoke_func->Params().size(); + for (size_t i = 0; i < nargs; i++) { + auto const *const param = invoke_func->Params()[i]->AsETSParameterExpression(); + auto *const param_ident = Allocator()->New(param->Ident()->Name(), Allocator()); + param_ident->SetVariable(param->Variable()); + param_ident->SetTsType(param->Variable()->TsType()); + + auto *lambda_param = lambda->Function()->Params()[i]->AsETSParameterExpression(); + auto *const param_cast = + Allocator()->New(param_ident, lambda_param->TypeAnnotation(), false); + param_cast->Check(this); + call_params.push_back(param_cast); + } + } else { + ASSERT(invoke_func->Params().size() == 1); + auto const *const param = invoke_func->Params()[0]->AsETSParameterExpression(); auto *const param_ident = Allocator()->New(param->Ident()->Name(), Allocator()); param_ident->SetVariable(param->Variable()); param_ident->SetTsType(param->Variable()->TsType()); - call_params.push_back(param_ident); + + for (size_t i = 0; i < params_num; i++) { + auto *idx = Allocator()->New(lexer::Number(static_cast(i))); + auto *arg = Allocator()->New(param_ident, idx, + ir::MemberExpressionKind::ELEMENT_ACCESS, true, false); + + auto *lambda_param = lambda->Function()->Params()[i]->AsETSParameterExpression(); + auto *const param_cast = Allocator()->New(arg, lambda_param->TypeAnnotation(), false); + param_cast->Check(this); + call_params.push_back(param_cast); + } } // Create the synthetic call expression to the proxy method @@ -1446,6 +1436,11 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition if (proxy_signature->ReturnType()->IsETSVoidType()) { return Allocator()->New(resolved_call); } + + if (iface_override && resolved_call->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + resolved_call->AddBoxingUnboxingFlag(GetBoxingFlag(resolved_call->TsType())); + } + return Allocator()->New(resolved_call); } @@ -1453,7 +1448,7 @@ void ETSChecker::ResolveLambdaObjectCtor(ir::ClassDefinition *lambda_object) { const auto &lambda_body = lambda_object->Body(); auto *lambda_object_type = lambda_object->TsType()->AsETSObjectType(); - auto *ctor_func = lambda_body[lambda_body.size() - 2]->AsMethodDefinition()->Function(); + auto *ctor_func = lambda_body[lambda_body.size() - 3]->AsMethodDefinition()->Function(); // Set the implicit 'this' parameters type to the lambda object auto *this_var = ctor_func->Scope()->ParamScope()->Params().front(); @@ -1971,15 +1966,17 @@ void ETSChecker::CreateLambdaObjectForFunctionReference(ir::AstNode *ref_node, S // 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 *invoke_func = CreateLambdaInvokeProto(); + auto *invoke0_func = CreateLambdaInvokeProto("invoke0"); + auto *invoke_func = CreateLambdaInvokeProto("invoke"); + properties.push_back(invoke0_func); properties.push_back(invoke_func); // Create the declarations for the synthetic constructor and invoke method CreateLambdaFuncDecl(ctor, class_scope->StaticMethodScope()); + CreateLambdaFuncDecl(invoke0_func, class_scope->InstanceMethodScope()); CreateLambdaFuncDecl(invoke_func, class_scope->InstanceMethodScope()); // Create the synthetic lambda class node - ArenaVector implements(Allocator()->Adapter()); auto *ident_node = Allocator()->New(util::StringView("LambdaObject"), Allocator()); auto *lambda_object = Allocator()->New(Allocator(), class_scope, ident_node, std::move(properties), @@ -1987,6 +1984,7 @@ void ETSChecker::CreateLambdaObjectForFunctionReference(ir::AstNode *ref_node, S // Set the parent nodes ctor->SetParent(lambda_object); + invoke0_func->SetParent(lambda_object); invoke_func->SetParent(lambda_object); class_scope->BindNode(lambda_object); @@ -2081,11 +2079,11 @@ std::tuple ETSChecker::C return {param_ctx.GetScope(), nullptr}; } -ir::MethodDefinition *ETSChecker::CreateLambdaInvokeProto() +ir::MethodDefinition *ETSChecker::CreateLambdaInvokeProto(util::StringView invoke_name) { // 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(invoke_name, Allocator()); auto *param_scope = VarBinder()->Allocator()->New(Allocator(), VarBinder()->GetScope()); auto *scope = VarBinder()->Allocator()->New(Allocator(), param_scope); @@ -2165,13 +2163,15 @@ void ETSChecker::ResolveLambdaObject(ir::ClassDefinition *lambda_object, Signatu ResolveLambdaObjectCtor(lambda_object, is_static_reference); // Resolve the invoke function - ResolveLambdaObjectInvoke(lambda_object, signature); + ResolveLambdaObjectInvoke(lambda_object, signature, true); + + ResolveLambdaObjectInvoke(lambda_object, signature, false); } void ETSChecker::ResolveLambdaObjectCtor(ir::ClassDefinition *lambda_object, bool is_static_reference) { const auto &lambda_body = lambda_object->Body(); - auto *ctor_func = lambda_body[lambda_body.size() - 2]->AsMethodDefinition()->Function(); + auto *ctor_func = lambda_body[lambda_body.size() - 3]->AsMethodDefinition()->Function(); ETSObjectType *lambda_object_type = lambda_object->TsType()->AsETSObjectType(); varbinder::Variable *field_var {}; @@ -2229,10 +2229,11 @@ void ETSChecker::ResolveLambdaObjectCtor(ir::ClassDefinition *lambda_object, boo fieldinit->Right()->SetTsType(ctor_signature->Params()[0]->TsType()); } -void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, Signature *signature_ref) +void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, Signature *signature_ref, + bool iface_override) { const auto &lambda_body = lambda_object->Body(); - auto *invoke_func = lambda_body[lambda_body.size() - 1]->AsMethodDefinition()->Function(); + auto *invoke_func = lambda_body[lambda_body.size() - (iface_override ? 2 : 1)]->AsMethodDefinition()->Function(); ETSObjectType *lambda_object_type = lambda_object->TsType()->AsETSObjectType(); // Set the implicit 'this' parameters type to the lambda object @@ -2244,23 +2245,44 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, S invoke_signature_info->rest_var = nullptr; // Create the parameters for the invoke function, based on the referenced function's signature - for (auto *it : signature_ref->Params()) { + + auto N = GlobalBuiltinFunctionTypeVariadicThreshold(); + + auto params_num = signature_ref->Params().size(); + + if (params_num < N || !iface_override) { + for (auto *it : signature_ref->Params()) { + auto param_ctx = varbinder::LexicalScope::Enter( + VarBinder(), invoke_func->Scope()->ParamScope(), false); + + auto *param_ident = Allocator()->New(it->Name(), Allocator()); + auto *param = Allocator()->New(param_ident, nullptr); + auto [_, var] = VarBinder()->AddParamDecl(param); + (void)_; + var->SetTsType(iface_override ? GlobalETSObjectType() : it->TsType()); + param_ident->SetVariable(var); + invoke_func->Params().push_back(param); + invoke_signature_info->min_arg_count++; + invoke_signature_info->params.push_back(var->AsLocalVariable()); + } + } else { auto param_ctx = varbinder::LexicalScope::Enter( VarBinder(), invoke_func->Scope()->ParamScope(), false); - auto *param_ident = Allocator()->New(it->Name(), Allocator()); - auto *param = Allocator()->New(param_ident, nullptr); + auto *id = AllocNode("p", Allocator()); + auto *rest_element = AllocNode(ir::AstNodeType::REST_ELEMENT, Allocator(), id); + auto *const param = AllocNode(rest_element, nullptr); auto [_, var] = VarBinder()->AddParamDecl(param); (void)_; - var->SetTsType(it->TsType()); - param_ident->SetVariable(var); + var->SetTsType(CreateETSArrayType(GlobalETSObjectType())); + param->Ident()->SetVariable(var); invoke_func->Params().push_back(param); - invoke_signature_info->min_arg_count++; - invoke_signature_info->params.push_back(var->AsLocalVariable()); + invoke_signature_info->rest_var = var->AsLocalVariable(); } // Create the function type for the constructor - auto *invoke_signature = CreateSignature(invoke_signature_info, signature_ref->ReturnType(), invoke_func); + auto *invoke_signature = CreateSignature( + invoke_signature_info, iface_override ? GlobalETSObjectType() : signature_ref->ReturnType(), invoke_func); invoke_signature->SetOwner(lambda_object_type); invoke_signature->AddSignatureFlag(checker::SignatureFlags::CALL); @@ -2273,7 +2295,8 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, S // Fill out the type information for the body of the invoke function - auto *resolved_lambda_invoke_function_body = ResolveLambdaObjectInvokeFuncBody(lambda_object, signature_ref); + auto *resolved_lambda_invoke_function_body = + ResolveLambdaObjectInvokeFuncBody(lambda_object, signature_ref, iface_override); invoke_func->Body()->AsBlockStatement()->Statements().push_back(resolved_lambda_invoke_function_body); if (resolved_lambda_invoke_function_body->IsExpressionStatement()) { @@ -2282,7 +2305,7 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambda_object, S } ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition *lambda_object, - Signature *signature_ref) + Signature *signature_ref, bool iface_override) { const auto &lambda_body = lambda_object->Body(); bool is_static_reference = signature_ref->HasSignatureFlag(SignatureFlags::STATIC); @@ -2314,13 +2337,64 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition callee->SetTsType(signature_ref->OwnerVar()->TsType()); // Create the parameters for the referenced function call - auto *invoke_func = lambda_body[lambda_body.size() - 1]->AsMethodDefinition()->Function(); + auto *invoke_func = lambda_body[lambda_body.size() - (iface_override ? 2 : 1)]->AsMethodDefinition()->Function(); ArenaVector call_params(Allocator()->Adapter()); - for (size_t idx = 0; idx != signature_ref->Params().size(); idx++) { - auto *param_ident = Allocator()->New(signature_ref->Params()[idx]->Name(), Allocator()); - param_ident->SetVariable(invoke_func->Params()[idx]->AsETSParameterExpression()->Variable()); - param_ident->SetTsType(invoke_func->Params()[idx]->AsETSParameterExpression()->Variable()->TsType()); - call_params.push_back(param_ident); + + auto N = GlobalBuiltinFunctionTypeVariadicThreshold(); + + auto params_num = signature_ref->Params().size(); + + if (!iface_override) { + for (size_t idx = 0; idx != params_num; idx++) { + auto *param_ident = Allocator()->New(signature_ref->Params()[idx]->Name(), Allocator()); + param_ident->SetVariable(invoke_func->Params()[idx]->AsETSParameterExpression()->Variable()); + param_ident->SetTsType(invoke_func->Params()[idx]->AsETSParameterExpression()->Variable()->TsType()); + call_params.push_back(param_ident); + } + } else if (params_num < N) { + // Then we add the lambda functions parameters to the call + auto nargs = invoke_func->Params().size(); + for (size_t i = 0; i < nargs; i++) { + auto const *const param = invoke_func->Params()[i]->AsETSParameterExpression(); + auto *const param_ident = Allocator()->New(param->Ident()->Name(), Allocator()); + param_ident->SetVariable(param->Variable()); + param_ident->SetTsType(param->Variable()->TsType()); + + auto *type = signature_ref->Params()[i]->TsType(); + if (type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + param_ident->AddBoxingUnboxingFlag(GetUnboxingFlag(type)); + call_params.push_back(param_ident); + } else { + const checker::CastingContext ctx(Relation(), param_ident, param_ident->TsType(), type, + param_ident->Start(), {}); + auto *const param_cast = Allocator()->New(param_ident, nullptr, false); + param_cast->SetUncheckedCast(ctx.UncheckedCast()); + param_cast->SetTsType(type); + call_params.push_back(param_cast); + } + } + } else { + ASSERT(invoke_func->Params().size() == 1); + auto const *const param = invoke_func->Params()[0]->AsETSParameterExpression(); + auto *const param_ident = Allocator()->New(param->Ident()->Name(), Allocator()); + param_ident->SetVariable(param->Variable()); + param_ident->SetTsType(param->Variable()->TsType()); + + for (size_t i = 0; i < params_num; i++) { + auto *idx = Allocator()->New(lexer::Number(static_cast(i))); + auto *arg = Allocator()->New(param_ident, idx, + ir::MemberExpressionKind::ELEMENT_ACCESS, true, false); + + auto *type = signature_ref->Params()[i]->TsType(); + if (type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + arg->AddBoxingUnboxingFlag(GetUnboxingFlag(type)); + call_params.push_back(arg); + } else { + auto *const param_cast = Allocator()->New(arg, nullptr, false); + param_cast->SetTsType(type); + call_params.push_back(param_cast); + } + } } // Create the synthetic call expression to the referenced function @@ -2332,6 +2406,10 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition return Allocator()->New(resolved_call); } + if (iface_override && resolved_call->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + resolved_call->AddBoxingUnboxingFlag(GetBoxingFlag(resolved_call->TsType())); + } + return Allocator()->New(resolved_call); } @@ -2622,4 +2700,22 @@ void ETSChecker::EnsureValidCurlyBrace(ir::CallExpression *call_expr) ThrowTypeError({"No matching call signature with trailing lambda"}, call_expr->Start()); } + +ETSObjectType *ETSChecker::GetFunctionalInterface(ir::ETSFunctionType *type) +{ + auto hash = GetHashFromFunctionType(type); + auto it = functional_interface_cache_.find(hash); + if (it == functional_interface_cache_.cend()) { + return nullptr; + } + return it->second; +} + +void ETSChecker::CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectType *iface_type) +{ + auto hash = GetHashFromFunctionType(type); + ASSERT(functional_interface_cache_.find(hash) == functional_interface_cache_.cend()); + functional_interface_cache_.emplace(hash, iface_type); +} + } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index b1f99ba5be..5520f189d2 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2023,6 +2023,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(); + TypeToString(ss, GetTypeFromTypeAnnotation(param->TypeAnnotation())); + ss << ";"; + } + + TypeToString(ss, type->ReturnType()->GetType(this)); + 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()) { diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 9ae05f1775..571fd51dc1 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -249,6 +249,7 @@ void ETSChecker::CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type : type->GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); type->SetTypeArguments(CreateTypeForTypeParameters(type_params)); type->AddObjectFlag(ETSObjectFlags::RESOLVED_TYPE_PARAMS); + type->AddObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION); } ETSObjectType *ETSChecker::BuildInterfaceProperties(ir::TSInterfaceDeclaration *interface_decl) @@ -1410,7 +1411,12 @@ ETSObjectType *ETSChecker::GetTypeargumentedLUB(ETSObjectType *const source, ETS const util::StringView hash = GetHashFromTypeArguments(params); - ETSObjectType *template_type = source->GetDeclNode()->AsClassDefinition()->TsType()->AsETSObjectType(); + ETSObjectType *template_type; + if (source->GetDeclNode()->IsClassDefinition()) { + template_type = source->GetDeclNode()->AsClassDefinition()->TsType()->AsETSObjectType(); + } else { + template_type = source->GetDeclNode()->AsTSInterfaceDeclaration()->TsType()->AsETSObjectType(); + } auto *lub_type = template_type->GetInstantiatedType(hash); diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index ee23d08854..1b7a087353 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -39,7 +39,8 @@ bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSType ir::TSTypeParameterInstantiation *type_args, const lexer::SourcePosition &pos) { - if (type_param_decl != nullptr && type_args == nullptr) { + if (type_param_decl != nullptr && type_args == nullptr && + type->HasObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION)) { checker_->ThrowTypeError({"Type '", type, "' is generic but type argument were not provided."}, pos); } diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index b67c53ca99..ce8d1361bb 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -112,7 +112,7 @@ void ETSFunctionType::AssignmentTarget(TypeRelation *relation, Type *source) 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; } } @@ -122,11 +122,11 @@ void ETSFunctionType::AssignmentTarget(TypeRelation *relation, Type *source) } 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; } @@ -139,8 +139,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()); diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 7d060c93c5..7e4b095983 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -308,7 +308,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())) { @@ -330,51 +330,62 @@ void ETSObjectType::IdenticalUptoNullability(TypeRelation *relation, Type *other return; } - auto const other_type_arguments = other->AsETSObjectType()->TypeArguments(); + if (IsNullish()) { + relation->Result(true); + return; + } - if (HasTypeFlag(TypeFlag::GENERIC) || IsNullish()) { - if (!HasTypeFlag(TypeFlag::GENERIC)) { - relation->Result(true); - return; - } - if (type_arguments_.empty() != other_type_arguments.empty()) { - return; - } + auto const source_type_arguments = other->AsETSObjectType()->TypeArguments(); + if (type_arguments_.empty() != source_type_arguments.empty()) { + return; + } - auto const args_number = type_arguments_.size(); - ASSERT(args_number == other_type_arguments.size()); + if (HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { + auto get_invoke_signature = [](const ETSObjectType *type) { + auto const prop_invoke = + type->GetProperty(util::StringView("invoke"), PropertySearchFlags::SEARCH_INSTANCE_METHOD); + ASSERT(prop_invoke != nullptr); + return prop_invoke->TsType()->AsETSFunctionType()->CallSignatures()[0]; + }; - for (size_t idx = 0U; idx < args_number; ++idx) { - if (type_arguments_[idx]->IsWildcardType() || other_type_arguments[idx]->IsWildcardType()) { - continue; - } + auto *const this_invoke_signature = get_invoke_signature(this); + auto *const other_invoke_signature = get_invoke_signature(other->AsETSObjectType()); + + relation->IsIdenticalTo(this_invoke_signature, other_invoke_signature); + return; + } - const auto get_original_base_type_or_type = [&relation](Type *const original_type) { - auto *const base_type = relation->GetChecker()->AsETSChecker()->GetOriginalBaseType(original_type); - return base_type == nullptr ? original_type : base_type; - }; + relation->Result(true); +} - auto *const type_arg_type = get_original_base_type_or_type(type_arguments_[idx]); - auto *const other_type_arg_type = get_original_base_type_or_type(other_type_arguments[idx]); +void ETSObjectType::IdenticalUptoNullability(TypeRelation *relation, Type *other) +{ + IdenticalUptoNullabilityAndTypeArguments(relation, other); - type_arg_type->Identical(relation, other_type_arg_type); - if (!relation->IsTrue()) { - return; - } + if (!relation->IsTrue() || !HasTypeFlag(TypeFlag::GENERIC)) { + return; + } + + auto const other_type_arguments = other->AsETSObjectType()->TypeArguments(); + + auto const args_number = type_arguments_.size(); + ASSERT(args_number == other_type_arguments.size()); + + for (size_t idx = 0U; idx < args_number; ++idx) { + if (type_arguments_[idx]->IsWildcardType() || other_type_arguments[idx]->IsWildcardType()) { + continue; } - } else { - if (HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { - auto get_invoke_signature = [](const ETSObjectType *type) { - auto const prop_invoke = - type->GetProperty(util::StringView("invoke"), PropertySearchFlags::SEARCH_INSTANCE_METHOD); - ASSERT(prop_invoke != nullptr); - return prop_invoke->TsType()->AsETSFunctionType()->CallSignatures()[0]; - }; - auto *const this_invoke_signature = get_invoke_signature(this); - auto *const other_invoke_signature = get_invoke_signature(other->AsETSObjectType()); + const auto get_original_base_type_or_type = [&relation](Type *const original_type) { + auto *const base_type = relation->GetChecker()->AsETSChecker()->GetOriginalBaseType(original_type); + return base_type == nullptr ? original_type : base_type; + }; + + auto *const type_arg_type = get_original_base_type_or_type(type_arguments_[idx]); + auto *const other_type_arg_type = get_original_base_type_or_type(other_type_arguments[idx]); - relation->IsIdenticalTo(this_invoke_signature, other_invoke_signature); + type_arg_type->Identical(relation, other_type_arg_type); + if (!relation->IsTrue()) { return; } } @@ -646,7 +657,12 @@ void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) return; } - IdenticalUptoNullability(relation, source); + IdenticalUptoNullabilityAndTypeArguments(relation, source); + + if (relation->IsTrue() && HasTypeFlag(TypeFlag::GENERIC)) { + IsGenericSupertypeOf(relation, source); + } + if (relation->IsTrue()) { return; } @@ -669,6 +685,51 @@ void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) } } +void ETSObjectType::IsGenericSupertypeOf(TypeRelation *relation, Type *source) +{ + ASSERT(HasTypeFlag(TypeFlag::GENERIC)); + + auto *source_type = source->AsETSObjectType(); + auto const source_type_arguments = source_type->TypeArguments(); + ASSERT(type_arguments_.size() == source_type_arguments.size()); + + ASSERT(decl_node_ == source_type->GetDeclNode()); + + auto *type_params_decl = GetTypeParams(); + ASSERT(type_params_decl != nullptr || type_arguments_.empty()); + + if (type_params_decl == nullptr) { + return; + } + + auto &type_params = type_params_decl->Params(); + ASSERT(type_params.size() == type_arguments_.size()); + + for (size_t idx = 0; idx < type_arguments_.size(); idx++) { + auto *type_arg = type_arguments_[idx]; + auto *source_type_arg = source_type_arguments[idx]; + auto *type_param = type_params[idx]; + + relation->Result(false); + + if (!(type_arg->IsWildcardType() || source_type_arg->IsWildcardType())) { + if (type_param->IsOut()) { + type_arg->IsSupertypeOf(relation, source_type_arg); + } else if (type_param->IsIn()) { + source_type_arg->IsSupertypeOf(relation, type_arg); + } else { + type_arg->Identical(relation, source_type_arg); + } + + if (!relation->IsTrue()) { + return; + } + } + } + + relation->Result(true); +} + Type *ETSObjectType::AsSuper(Checker *checker, varbinder::Variable *source_var) { if (source_var == nullptr) { @@ -797,7 +858,7 @@ ETSObjectType const *ETSObjectType::GetConstOriginalBaseType() const noexcept return this; } -Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution) +Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution, bool cache) { if (substitution == nullptr || substitution->empty()) { return this; @@ -841,8 +902,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()) { @@ -861,7 +924,9 @@ Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *subs copied_type->relation_ = relation; copied_type->substitution_ = substitution; - GetInstantiationMap().try_emplace(hash, copied_type); + if (cache) { + GetInstantiationMap().try_emplace(hash, copied_type); + } if (super_type_ != nullptr) { copied_type->SetSuperType(super_type_->Substitute(relation, substitution)->AsETSObjectType()); @@ -876,6 +941,11 @@ Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *subs return copied_type; } +Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution) +{ + return Substitute(relation, substitution, true); +} + void ETSObjectType::InstantiateProperties() const { if (base_type_ == nullptr || base_type_ == this) { diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index a083979f86..c7de270379 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -414,17 +414,11 @@ public: varbinder::Scope *GetTypeArgumentScope() const { - if (HasObjectFlag(ETSObjectFlags::ENUM) || !HasTypeFlag(TypeFlag::GENERIC)) { + auto *type_params = GetTypeParams(); + if (type_params == nullptr) { return nullptr; } - - if (HasObjectFlag(ETSObjectFlags::CLASS)) { - ASSERT(decl_node_->IsClassDefinition() && decl_node_->AsClassDefinition()->TypeParams()); - return decl_node_->AsClassDefinition()->TypeParams()->Scope(); - } - - ASSERT(decl_node_->IsTSInterfaceDeclaration() && decl_node_->AsTSInterfaceDeclaration()->TypeParams()); - return decl_node_->AsTSInterfaceDeclaration()->TypeParams()->Scope(); + return type_params->Scope(); } InstantiationMap &GetInstantiationMap() @@ -478,6 +472,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *global_types) override; Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; + Type *Substitute(TypeRelation *relation, const Substitution *substitution, bool cache); void Cast(TypeRelation *relation, Type *target) override; bool CastNumericObject(TypeRelation *relation, Type *target); void IsSupertypeOf(TypeRelation *relation, Type *source) override; @@ -551,6 +546,24 @@ private: } std::unordered_map CollectAllProperties() const; void IdenticalUptoNullability(TypeRelation *relation, Type *other); + void IdenticalUptoNullabilityAndTypeArguments(TypeRelation *relation, Type *other); + void IsGenericSupertypeOf(TypeRelation *relation, Type *source); + + ir::TSTypeParameterDeclaration *GetTypeParams() const + { + if (HasObjectFlag(ETSObjectFlags::ENUM) || HasObjectFlag(ETSObjectFlags::TYPE_PARAMETER) || + !HasTypeFlag(TypeFlag::GENERIC)) { + return nullptr; + } + + if (HasObjectFlag(ETSObjectFlags::CLASS)) { + ASSERT(decl_node_->IsClassDefinition() && decl_node_->AsClassDefinition()->TypeParams()); + return decl_node_->AsClassDefinition()->TypeParams(); + } + + ASSERT(decl_node_->IsTSInterfaceDeclaration() && decl_node_->AsTSInterfaceDeclaration()->TypeParams()); + return decl_node_->AsTSInterfaceDeclaration()->TypeParams(); + } ArenaAllocator *allocator_; util::StringView name_; diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index 50e7839a53..ef54b16528 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -156,6 +156,18 @@ GlobalTypesHolder::GlobalTypesHolder(ArenaAllocator *allocator) : builtin_name_m builtin_name_mappings_.emplace("RegExp", GlobalTypeId::ETS_REGEXP_BUILTIN); builtin_name_mappings_.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; + + builtin_name_mappings_.emplace(util::UString(ss.str(), allocator).View(), static_cast(id)); + } + + builtin_name_mappings_.emplace("FunctionN", GlobalTypeId::ETS_FUNCTIONN_CLASS); + // ETS interop js specific types builtin_name_mappings_.emplace("JSRuntime", GlobalTypeId::ETS_INTEROP_JSRUNTIME_BUILTIN); builtin_name_mappings_.emplace("JSValue", GlobalTypeId::ETS_INTEROP_JSVALUE_BUILTIN); @@ -596,6 +608,11 @@ Type *GlobalTypesHolder::GlobalBuiltinNeverType() return global_types_.at(static_cast(GlobalTypeId::ETS_NEVER_BUILTIN)); } +Type *GlobalTypesHolder::GlobalFunctionBuiltinType(size_t nargs) +{ + return global_types_.at(static_cast(GlobalTypeId::ETS_FUNCTION0_CLASS) + nargs); +} + void GlobalTypesHolder::InitializeBuiltin(const util::StringView name, Type *type) { const auto type_id = builtin_name_mappings_.find(name); diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index e84ae6ad35..0e8fd278d6 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -109,6 +109,25 @@ enum class GlobalTypeId { ETS_DOUBLE_BOX_BUILTIN, ETS_NEVER_BUILTIN, + 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, }; @@ -198,6 +217,9 @@ public: Type *GlobalDoubleBoxBuiltinType(); Type *GlobalBuiltinNeverType(); + // Functional types + Type *GlobalFunctionBuiltinType(size_t nargs); + // ETS escompat layer Type *GlobalArrayBuiltinType(); Type *GlobalClassOutOfMemoryErrorBuiltinType(); diff --git a/ets2panda/checker/types/signature.h b/ets2panda/checker/types/signature.h index 2341dd5745..9d8ff51d2a 100644 --- a/ets2panda/checker/types/signature.h +++ b/ets2panda/checker/types/signature.h @@ -80,6 +80,8 @@ enum class SignatureFlags : uint32_t { NEED_RETURN_TYPE = 1U << 13U, INFERRED_RETURN_TYPE = 1U << 14U, SUBSTITUTED_RETURN_TYPE = 1U << 15U, + THROWS = 1U << 16U, + RETHROWS = 1U << 17U, INTERNAL_PROTECTED = INTERNAL | PROTECTED, FUNCTIONAL_INTERFACE_SIGNATURE = VIRTUAL | ABSTRACT | CALL | PUBLIC | TYPE diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 30b8519653..dd44ebf93a 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -870,7 +870,7 @@ bool ETSGen::TryLoadConstantExpression(const ir::Expression *node) // NOTE: vpukhov. lower (union_value) as (primitive_type) to be two as-nodes static void ApplyUnboxingUnionPrimitive(ETSGen *etsg, const ir::AstNode *node) { - if (node->IsExpression() && node->Parent()->IsTSAsExpression()) { + if (node->IsExpression() && node->Parent() && node->Parent()->IsTSAsExpression()) { auto const *from_type = node->AsExpression()->TsType(); auto const *to_type = node->Parent()->AsTSAsExpression()->TsType(); if (from_type->IsETSUnionType() && to_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { @@ -980,41 +980,73 @@ void ETSGen::EmitUnboxingConversion(const ir::AstNode *node) switch (unboxing_flag) { case ir::BoxingUnboxingFlags::UNBOX_TO_BOOLEAN: { + auto *boxed_type = Checker()->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); + if (GetAccumulatorType() != boxed_type) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_UNBOXED, dummy_reg_, 0); SetAccumulatorType(Checker()->GlobalETSBooleanType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_BYTE: { + auto *boxed_type = Checker()->GetGlobalTypesHolder()->GlobalByteBuiltinType(); + if (GetAccumulatorType() != boxed_type) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } Ra().Emit(node, Signatures::BUILTIN_BYTE_UNBOXED, dummy_reg_, 0); SetAccumulatorType(Checker()->GlobalByteType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_CHAR: { + auto *boxed_type = Checker()->GetGlobalTypesHolder()->GlobalCharBuiltinType(); + if (GetAccumulatorType() != boxed_type) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } Ra().Emit(node, Signatures::BUILTIN_CHAR_UNBOXED, dummy_reg_, 0); SetAccumulatorType(Checker()->GlobalCharType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_SHORT: { + auto *boxed_type = Checker()->GetGlobalTypesHolder()->GlobalShortBuiltinType(); + if (GetAccumulatorType() != boxed_type) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } Ra().Emit(node, Signatures::BUILTIN_SHORT_UNBOXED, dummy_reg_, 0); SetAccumulatorType(Checker()->GlobalShortType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_INT: { + auto *boxed_type = Checker()->GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); + if (GetAccumulatorType() != boxed_type) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } Ra().Emit(node, Signatures::BUILTIN_INT_UNBOXED, dummy_reg_, 0); SetAccumulatorType(Checker()->GlobalIntType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_LONG: { + auto *boxed_type = Checker()->GetGlobalTypesHolder()->GlobalLongBuiltinType(); + if (GetAccumulatorType() != boxed_type) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } Ra().Emit(node, Signatures::BUILTIN_LONG_UNBOXED, dummy_reg_, 0); SetAccumulatorType(Checker()->GlobalLongType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_FLOAT: { + auto *boxed_type = Checker()->GetGlobalTypesHolder()->GlobalFloatBuiltinType(); + if (GetAccumulatorType() != boxed_type) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } Ra().Emit(node, Signatures::BUILTIN_FLOAT_UNBOXED, dummy_reg_, 0); SetAccumulatorType(Checker()->GlobalFloatType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_DOUBLE: { + auto *boxed_type = Checker()->GetGlobalTypesHolder()->GlobalDoubleBuiltinType(); + if (GetAccumulatorType() != boxed_type) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } Ra().Emit(node, Signatures::BUILTIN_DOUBLE_UNBOXED, dummy_reg_, 0); SetAccumulatorType(Checker()->GlobalDoubleType()); break; diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 7ee98c5619..068cac4243 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -938,11 +938,16 @@ private: break; } default: { - for (const auto *arg : arguments) { + for (size_t idx = 0; idx < arguments.size(); idx++) { + auto *arg = arguments[idx]; + auto *paramType = Checker()->MaybeBoxedType( + idx < signature->Params().size() ? signature->Params()[idx] : signature->RestVar(), + Allocator()); auto ttctx = TargetTypeContext(this, arg->TsType()); VReg arg_reg = AllocReg(); arg->Compile(this); - StoreAccumulator(node, arg_reg); + ApplyConversion(arg, nullptr); + ApplyConversionAndStoreAccumulator(arg, arg_reg, paramType); } Rra().Emit(node, ctor, arguments.size() + 1, name, ctor); @@ -997,11 +1002,16 @@ private: default: { VReg arg_start = NextReg(); - for (const auto *arg : arguments) { + for (size_t idx = 0; idx < arguments.size(); idx++) { + auto *arg = arguments[idx]; + auto *paramType = Checker()->MaybeBoxedType( + idx < signature->Params().size() ? signature->Params()[idx] : signature->RestVar(), + Allocator()); auto ttctx = TargetTypeContext(this, arg->TsType()); VReg arg_reg = AllocReg(); arg->Compile(this); - StoreAccumulator(node, arg_reg); + ApplyConversion(arg, nullptr); + ApplyConversionAndStoreAccumulator(arg, arg_reg, paramType); } Rra().Emit(node, arg_start, arguments.size(), name, arg_start); diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 0f2a2e8dc1..336d75dba8 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -287,6 +287,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 diff --git a/ets2panda/ir/ets/etsFunctionType.cpp b/ets2panda/ir/ets/etsFunctionType.cpp index 57e2248c56..6c16c5bde0 100644 --- a/ets2panda/ir/ets/etsFunctionType.cpp +++ b/ets2panda/ir/ets/etsFunctionType.cpp @@ -87,16 +87,63 @@ checker::Type *ETSFunctionType::GetType([[maybe_unused]] checker::TSChecker *che checker::Type *ETSFunctionType::Check(checker::ETSChecker *checker) { - checker->CreateFunctionalInterfaceForFunctionType(this); - auto *interface_type = checker->CreateETSObjectType(functional_interface_->Id()->Name(), functional_interface_, - checker::ETSObjectFlags::FUNCTIONAL_INTERFACE); - interface_type->SetSuperType(checker->GlobalETSObjectType()); + auto *generic_interface_type = checker->GlobalBuiltinFunctionType(params_.size()); + functional_interface_ = generic_interface_type->GetDeclNode()->AsTSInterfaceDeclaration(); + + ts_type_ = checker->GetFunctionalInterface(this); + if (ts_type_ != nullptr) { + return ts_type_; + } auto *invoke_func = functional_interface_->Body()->Body()[0]->AsMethodDefinition()->Function(); + + auto *substitution = checker->NewSubstitution(); + + auto N = checker->GlobalBuiltinFunctionTypeVariadicThreshold(); + + size_t i = 0; + if (params_.size() < N) { + for (; i < params_.size(); i++) { + auto *param_type = + checker->GetTypeFromTypeAnnotation(params_[i]->AsETSParameterExpression()->TypeAnnotation()); + if (param_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + checker->Relation()->SetNode(params_[i]); + auto *const boxed_type_arg = checker->PrimitiveTypeAsETSBuiltinType(param_type); + ASSERT(boxed_type_arg); + param_type = boxed_type_arg->Instantiate(checker->Allocator(), checker->Relation(), + checker->GetGlobalTypesHolder()); + } + + substitution->emplace(generic_interface_type->TypeArguments()[i], param_type); + } + } + + auto *return_type = return_type_->GetType(checker); + if (return_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + checker->Relation()->SetNode(return_type_); + auto *const boxed_type_ret = checker->PrimitiveTypeAsETSBuiltinType(return_type); + return_type = + boxed_type_ret->Instantiate(checker->Allocator(), checker->Relation(), checker->GetGlobalTypesHolder()); + } + + substitution->emplace(generic_interface_type->TypeArguments()[i], return_type); + + auto *interface_type = + generic_interface_type->Substitute(checker->Relation(), substitution, false)->AsETSObjectType(); + + util::StringView invoke_name = "invoke"; + auto *invoke_variable = interface_type->GetOwnProperty(invoke_name); + ASSERT(invoke_variable == nullptr); + + auto *decl = checker->Allocator()->New(checker->Allocator(), invoke_name, + interface_type->GetDeclNode()); + invoke_variable = checker->Allocator()->New(decl, varbinder::VariableFlags::SYNTHETIC | + varbinder::VariableFlags::METHOD); + auto *signature_info = checker->Allocator()->New(checker->Allocator()); - for (auto *it : invoke_func->Params()) { - auto *const param = it->AsETSParameterExpression(); + for (auto *p : params_) { + auto *const param = p->AsETSParameterExpression(); if (param->IsRestParameter()) { auto *rest_ident = param->Ident(); @@ -121,23 +168,27 @@ checker::Type *ETSFunctionType::Check(checker::ETSChecker *checker) } } - invoke_func->ReturnTypeAnnotation()->Check(checker); auto *signature = checker->Allocator()->New(signature_info, return_type_->GetType(checker), invoke_func); - signature->SetOwnerVar(invoke_func->Id()->Variable()->AsLocalVariable()); + + signature->SetOwnerVar(invoke_variable); signature->AddSignatureFlag(checker::SignatureFlags::FUNCTIONAL_INTERFACE_SIGNATURE); signature->SetOwner(interface_type); - auto *func_type = checker->CreateETSFunctionType(signature); - invoke_func->SetSignature(signature); - invoke_func->Id()->Variable()->SetTsType(func_type); - interface_type->AddProperty( - invoke_func->Id()->Variable()->AsLocalVariable()); - functional_interface_->SetTsType(interface_type); + if (IsThrowing()) { + signature->AddSignatureFlag(checker::SignatureFlags::THROWS); + } + + if (IsRethrowing()) { + signature->AddSignatureFlag(checker::SignatureFlags::RETHROWS); + } - auto *this_var = invoke_func->Scope()->ParamScope()->Params().front(); - this_var->SetTsType(interface_type); - checker->BuildFunctionalInterfaceName(this); + auto *func_type = checker->CreateETSFunctionType(signature, invoke_name); + func_type->AddTypeFlag(checker::TypeFlag::SYNTHETIC); + invoke_variable->SetTsType(func_type); + interface_type->AddProperty(invoke_variable); + + checker->CacheFunctionalInterface(this, interface_type); ts_type_ = interface_type; return interface_type; @@ -147,4 +198,5 @@ checker::Type *ETSFunctionType::GetType(checker::ETSChecker *checker) { return Check(checker); } + } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ets/etsFunctionType.h b/ets2panda/ir/ets/etsFunctionType.h index 62c59ffd9f..6ece3f1861 100644 --- a/ets2panda/ir/ets/etsFunctionType.h +++ b/ets2panda/ir/ets/etsFunctionType.h @@ -85,6 +85,11 @@ public: return (func_flags_ & ir::ScriptFunctionFlags::THROWS) != 0; } + bool IsRethrowing() const + { + return (func_flags_ & 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/expressions/callExpression.cpp b/ets2panda/ir/expressions/callExpression.cpp index b74f16794d..2ae52c2d4b 100644 --- a/ets2panda/ir/expressions/callExpression.cpp +++ b/ets2panda/ir/expressions/callExpression.cpp @@ -87,11 +87,11 @@ compiler::VReg CallExpression::CreateSpreadArguments(compiler::PandaGen *pg) con return args_obj; } -void CallExpression::ConvertRestArguments(checker::ETSChecker *const checker) const +void CallExpression::ConvertRestArguments(checker::ETSChecker *const checker, checker::Signature *signature) const { - if (signature_->RestVar() != nullptr) { + if (signature->RestVar() != nullptr) { std::size_t const argument_count = arguments_.size(); - std::size_t const parameter_count = signature_->MinArgCount(); + std::size_t const parameter_count = signature->MinArgCount(); ASSERT(argument_count >= parameter_count); auto &arguments = const_cast &>(arguments_); @@ -106,13 +106,36 @@ void CallExpression::ConvertRestArguments(checker::ETSChecker *const checker) co } auto *array_expression = checker->AllocNode(std::move(elements), checker->Allocator()); array_expression->SetParent(const_cast(this)); - array_expression->SetTsType(signature_->RestVar()->TsType()); + array_expression->SetTsType(signature->RestVar()->TsType()); arguments.erase(arguments_.begin() + parameter_count, arguments_.end()); arguments.emplace_back(array_expression); } } } +void CallExpression::ConvertArgumentsForFunctionalCall(checker::ETSChecker *const checker) const +{ + std::size_t const argument_count = arguments_.size(); + auto &arguments = const_cast &>(arguments_); + + for (size_t i = 0; i < argument_count; i++) { + auto *param_type = checker->MaybeBoxedType( + i < signature_->Params().size() ? signature_->Params()[i] : signature_->RestVar(), checker->Allocator()); + + auto *expr = arguments_[i]; + auto *cast = checker->Allocator()->New(expr, nullptr, false); + arguments_[i]->SetParent(cast); + cast->SetParent(const_cast(this)); + cast->SetTsType(param_type); + + if (param_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + cast->AddBoxingUnboxingFlag(checker->GetBoxingFlag(param_type)); + } + + arguments[i] = cast; + } +} + void CallExpression::Compile(compiler::PandaGen *pg) const { compiler::RegScope rs(pg); @@ -252,23 +275,49 @@ void CallExpression::Compile(compiler::ETSGen *etsg) const bool is_reference = signature_->HasSignatureFlag(checker::SignatureFlags::TYPE); bool is_dynamic = callee_->TsType()->HasTypeFlag(checker::TypeFlag::ETS_DYNAMIC_FLAG); - ConvertRestArguments(const_cast(etsg->Checker()->AsETSChecker())); + checker::Signature *signature = signature_; + if (is_reference) { + auto *func_type = signature_->Owner() + ->GetOwnProperty("invoke0") + ->TsType() + ->AsETSFunctionType(); + ASSERT(func_type->CallSignatures().size() == 1); + signature = func_type->CallSignatures()[0]; + + if (signature_->ReturnType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + AddBoxingUnboxingFlag(const_cast(etsg->Checker()->AsETSChecker()) + ->GetUnboxingFlag(signature_->ReturnType())); + } + + ConvertArgumentsForFunctionalCall(const_cast(etsg->Checker()->AsETSChecker())); + } + + ConvertRestArguments(const_cast(etsg->Checker()->AsETSChecker()), signature); compiler::VReg dyn_param2; // Helper function to avoid branching in non optional cases - auto emit_call = [this, etsg, is_static, is_dynamic, &callee_reg, &dyn_param2]() { + auto emit_call = [this, etsg, is_static, is_dynamic, &callee_reg, &dyn_param2, signature, is_reference]() { if (is_dynamic) { - etsg->CallDynamic(this, callee_reg, dyn_param2, signature_, arguments_); + etsg->CallDynamic(this, callee_reg, dyn_param2, signature, arguments_); } else if (is_static) { - etsg->CallStatic(this, signature_, arguments_); - } else if (signature_->HasSignatureFlag(checker::SignatureFlags::PRIVATE) || IsETSConstructorCall() || + etsg->CallStatic(this, signature, arguments_); + } else if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE) || IsETSConstructorCall() || (callee_->IsMemberExpression() && callee_->AsMemberExpression()->Object()->IsSuperExpression())) { - etsg->CallThisStatic(this, callee_reg, signature_, arguments_); + etsg->CallThisStatic(this, callee_reg, signature, arguments_); } else { - etsg->CallThisVirtual(this, callee_reg, signature_, arguments_); + etsg->CallThisVirtual(this, callee_reg, signature, arguments_); + } + + if (GetBoxingUnboxingFlags() != ir::BoxingUnboxingFlags::NONE) { + etsg->ApplyConversion(this, nullptr); + } else { + if (is_reference) { + etsg->EmitCheckedNarrowingReferenceConversion(this, signature->ReturnType()); + } else { + etsg->SetAccumulatorType(signature->ReturnType()); + } } - etsg->SetAccumulatorType(TsType()); }; if (is_dynamic) { @@ -320,7 +369,7 @@ void CallExpression::Compile(compiler::ETSGen *etsg) const emit_call(); - if (signature_->ReturnType() != TsType()) { + if (signature->ReturnType() != TsType()) { etsg->ApplyConversion(this, TsType()); } } else if (!is_reference && callee_->IsIdentifier()) { @@ -484,7 +533,9 @@ checker::Type *CallExpression::Check(checker::ETSChecker *checker) ASSERT(signature->Function() != nullptr); - if (signature->Function()->IsThrowing() || signature->Function()->IsRethrowing()) { + if (signature->Function()->IsThrowing() || signature->Function()->IsRethrowing() || + signature->HasSignatureFlag(checker::SignatureFlags::THROWS) || + signature->HasSignatureFlag(checker::SignatureFlags::RETHROWS)) { checker->CheckThrowingStatements(this); } diff --git a/ets2panda/ir/expressions/callExpression.h b/ets2panda/ir/expressions/callExpression.h index d68ca9daca..b0f0656530 100644 --- a/ets2panda/ir/expressions/callExpression.h +++ b/ets2panda/ir/expressions/callExpression.h @@ -149,7 +149,8 @@ private: bool IsETSConstructorCall() const; checker::Type *InitAnonymousLambdaCallee(checker::ETSChecker *checker, Expression *callee, checker::Type *callee_type); - void ConvertRestArguments(checker::ETSChecker *checker) const; + void ConvertRestArguments(checker::ETSChecker *checker, checker::Signature *signature) const; + void ConvertArgumentsForFunctionalCall(checker::ETSChecker *checker) const; }; } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsAsExpression.h b/ets2panda/ir/ts/tsAsExpression.h index 549851835e..606e8bcf9b 100644 --- a/ets2panda/ir/ts/tsAsExpression.h +++ b/ets2panda/ir/ts/tsAsExpression.h @@ -42,6 +42,11 @@ public: return is_const_; } + void SetUncheckedCast(bool is_unchecked_cast) + { + is_unchecked_cast_ = is_unchecked_cast; + } + 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/function_subtyping_1-expected.txt b/ets2panda/test/compiler/ets/function_subtyping_1-expected.txt new file mode 100644 index 0000000000..ca68775f5e --- /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 0000000000..0b2ffc867e --- /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 0000000000..238ecc795e --- /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: Initializers type is not assignable to the target type [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 0000000000..64860a92b8 --- /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 0000000000..fda24531eb --- /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: Initializers type is not assignable to the target type [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 0000000000..4e57a855ae --- /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 0000000000..abef87ab4c --- /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 0000000000..dee382251f --- /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 0000000000..fc0a7b29c8 --- /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: Initializers type is not assignable to the target type [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 0000000000..a3bc04b211 --- /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 0000000000..bcc29945b2 --- /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: Initializers type is not assignable to the target type [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 0000000000..2b61cf9302 --- /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 0000000000..3779e62e1d --- /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: Initializers type is not assignable to the target type [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 0000000000..bc98518302 --- /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 0000000000..ee4946496f --- /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: Initializers type is not assignable to the target type [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 0000000000..9e351ad8f9 --- /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/parser/ets/interface-expected.txt b/ets2panda/test/parser/ets/interface-expected.txt index a84f38f68d..13e389abc2 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 e43e384d53..80534bb52c 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 b814441ff1..4ac2df4d2f 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 ab0d8043f4..dff441fc21 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 @@ -1993,4 +1993,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/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index cd271713f1..2a17099abe 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -364,8 +364,9 @@ void ETSBinder::BuildLambdaObject(ir::AstNode *ref_node, ir::ClassDefinition *la auto bound_ctx = BoundContext(GetGlobalRecordTable(), lambda_object); const auto &lambda_body = lambda_object->Body(); + AddLambdaFunctionThisParam(lambda_body[lambda_body.size() - 3U]->AsMethodDefinition()->Function()); AddLambdaFunctionThisParam(lambda_body[lambda_body.size() - 2U]->AsMethodDefinition()->Function()); - AddLambdaFunctionThisParam(lambda_body[lambda_body.size() - 1]->AsMethodDefinition()->Function()); + AddLambdaFunctionThisParam(lambda_body[lambda_body.size() - 1U]->AsMethodDefinition()->Function()); LambdaObjects().insert({ref_node, {lambda_object, signature}}); } @@ -725,16 +726,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 *ref_node) { auto found = lambda_objects_.find(ref_node); @@ -762,53 +753,19 @@ void ETSBinder::BuildLambdaObjectName(const ir::AstNode *ref_node) lambda_object->SetAssemblerName(lambda_class->Ident()->Name()); const auto &lambda_body = lambda_class->Body(); - auto *ctor_func = lambda_body[lambda_body.size() - 2]->AsMethodDefinition()->Function(); + auto *ctor_func = lambda_body[lambda_body.size() - 3]->AsMethodDefinition()->Function(); auto *ctor_func_scope = ctor_func->Scope(); ctor_func_scope->BindName(lambda_class->Ident()->Name()); + auto *invoke0_func = lambda_body[lambda_body.size() - 2]->AsMethodDefinition()->Function(); + auto *invoke0_func_scope = invoke0_func->Scope(); + invoke0_func_scope->BindName(lambda_class->Ident()->Name()); + auto *invoke_func = lambda_body[lambda_body.size() - 1]->AsMethodDefinition()->Function(); auto *invoke_func_scope = invoke_func->Scope(); invoke_func_scope->BindName(lambda_class->Ident()->Name()); } -void ETSBinder::BuildFunctionalInterfaceName(ir::ETSFunctionType *func_type) -{ - auto *functional_interface = func_type->FunctionalInterface(); - auto *invoke_func = functional_interface->Body()->Body()[0]->AsMethodDefinition()->Function(); - util::UString functional_interface_name(functional_interface->Id()->Name(), Allocator()); - std::stringstream ss; - invoke_func->Signature()->ToAssemblerType(GetCompilerContext(), ss); - std::string signature_string = ss.str(); - util::StringView signature_name(signature_string); - FormFunctionalInterfaceName(functional_interface_name, signature_name); - functional_interface->Id()->SetName(functional_interface_name.View()); - util::UString internal_name(Program()->GetPackageName(), Allocator()); - if (!(internal_name.View().Empty())) { - internal_name.Append(compiler::Signatures::METHOD_SEPARATOR); - } - internal_name.Append(functional_interface->Id()->Name()); - functional_interface->SetInternalName(internal_name.View()); - - checker::ETSObjectType *functional_interface_type = functional_interface->TsType()->AsETSObjectType(); - functional_interface_type->SetName(functional_interface->Id()->Name()); - functional_interface_type->SetAssemblerName(internal_name.View()); - - auto *invoke_func_scope = invoke_func->Scope(); - invoke_func_scope->BindName(functional_interface->Id()->Name()); - - util::UString invoke_internal_name(Program()->GetPackageName(), Allocator()); - if (!(invoke_internal_name.View().Empty())) { - invoke_internal_name.Append(compiler::Signatures::METHOD_SEPARATOR); - } - invoke_internal_name.Append(invoke_func_scope->Name()); - invoke_internal_name.Append(compiler::Signatures::METHOD_SEPARATOR); - invoke_internal_name.Append(invoke_func->Id()->Name()); - std::stringstream invoke_signature_ss; - invoke_func->Signature()->ToAssemblerType(GetCompilerContext(), invoke_signature_ss); - invoke_internal_name.Append(invoke_signature_ss.str()); - invoke_func_scope->BindInternalName(invoke_internal_name.View()); -} - void ETSBinder::InitImplicitThisParam() { this_param_ = Allocator()->New("this", Allocator()); diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 32b7feae10..efdaa2c871 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -150,8 +150,6 @@ public: void AddInvokeFunctionThisParam(ir::ScriptFunction *func); void BuildLambdaObjectName(const ir::AstNode *ref_node); void FormLambdaName(util::UString &name, const util::StringView &signature); - void FormFunctionalInterfaceName(util::UString &name, const util::StringView &signature); - void BuildFunctionalInterfaceName(ir::ETSFunctionType *func_type); void SetDefaultImports(ArenaVector default_imports) { -- Gitee