diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index a7e1743da9520853e500121cd9476dc03215aa97..57e41f9a4d019c74bd12491feea84b963d90cd49 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -459,6 +459,7 @@ public: bool IsNullLikeOrVoidExpression(const ir::Expression *expr) const; bool IsConstantExpression(ir::Expression *expr, Type *type); void ValidateUnaryOperatorOperand(varbinder::Variable *variable); + void InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::Expression *init); bool TestUnionType(Type *type, TypeFlag test); bool CheckPossibilityPromotion(Type *left, Type *right, TypeFlag test); std::tuple ApplyBinaryOperatorPromotion(Type *left, Type *right, TypeFlag test, diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 55b410391ce1210d4e5577ce39f5f9c981267d55..7d80dea86ef90dda1c2c289c741d5162287bda73 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -564,6 +564,37 @@ checker::Type *ETSChecker::CheckArrayElements(ir::Identifier *ident, ir::ArrayEx return annotationType; } +void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::Expression *init) +{ + if (localTypeAnnotation != nullptr && localTypeAnnotation->IsETSTypeReference()) { + bool isAnnotationTypeAlias = true; + while (localTypeAnnotation->IsETSTypeReference() && isAnnotationTypeAlias) { + auto *node = localTypeAnnotation->AsETSTypeReference() + ->Part() + ->Name() + ->AsIdentifier() + ->Variable() + ->Declaration() + ->Node(); + + isAnnotationTypeAlias = node->IsTSTypeAliasDeclaration(); + if (isAnnotationTypeAlias) { + localTypeAnnotation = node->AsTSTypeAliasDeclaration()->TypeAnnotation(); + } + } + } + + if (localTypeAnnotation != nullptr && localTypeAnnotation->IsETSFunctionType() && + init->IsArrowFunctionExpression()) { + auto *const arrowFuncExpr = init->AsArrowFunctionExpression(); + ir::ScriptFunction *const lambda = arrowFuncExpr->Function(); + if (lambda->Params().size() == localTypeAnnotation->AsETSFunctionType()->Params().size() && + NeedTypeInference(lambda)) { + InferTypesForLambda(lambda, localTypeAnnotation->AsETSFunctionType()); + } + } +} + checker::Type *ETSChecker::FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags) { if ((flags & ir::ModifierFlags::OPTIONAL) != 0) { @@ -633,14 +664,8 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T init->AsObjectExpression()->SetPreferredType(annotationType); } - if (typeAnnotation != nullptr && typeAnnotation->IsETSFunctionType() && init->IsArrowFunctionExpression()) { - auto *const arrowFuncExpr = init->AsArrowFunctionExpression(); - ir::ScriptFunction *const lambda = arrowFuncExpr->Function(); - if (lambda->Params().size() == typeAnnotation->AsETSFunctionType()->Params().size() && - NeedTypeInference(lambda)) { - InferTypesForLambda(lambda, typeAnnotation->AsETSFunctionType()); - } - } + InferAliasLambdaType(typeAnnotation, init); + checker::Type *initType = init->Check(this); if (initType == nullptr) {