From 8672704f08b9f6b0a1a8cfcec605b5ada3077f93 Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Sun, 1 Sep 2024 20:17:30 +0200 Subject: [PATCH] Fix issue with Null<> wrapped and non-null wrapped unification of typeParameters --- .../type/HaxeExpressionEvaluatorHandlers.java | 6 +++-- .../haxe/model/type/HaxeTypeUnifier.java | 27 ++++++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluatorHandlers.java b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluatorHandlers.java index d31786c21..4aef1c49e 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluatorHandlers.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluatorHandlers.java @@ -1352,7 +1352,8 @@ static ResultHolder handleCallExpression( } if (functionType instanceof SpecificFunctionReference ftype) { - ResultHolder returnType = ftype.getReturnType().tryUnwrapNullType(); + ResultHolder returnType = ftype.getReturnType(); + boolean nullWrapped = returnType.isNullWrappedType(); HaxeGenericResolver functionResolver = new HaxeGenericResolver(); functionResolver.addAll(resolver.withoutArgumentType()); @@ -1363,8 +1364,9 @@ static ResultHolder handleCallExpression( functionResolver.addAll(validation.getResolver()); } - ResultHolder resolved = functionResolver.resolveReturnType(returnType); + ResultHolder resolved = functionResolver.resolveReturnType(returnType.tryUnwrapNullType()); if (resolved != null && !resolved.isUnknown()) { + if(nullWrapped) resolved = resolved.wrapInNullType(); returnType = resolved; } if(returnType.isUnknown() || returnType.isDynamic() || returnType.isVoid()) { diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeUnifier.java b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeUnifier.java index 2c557e830..a6dbb9329 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeUnifier.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeUnifier.java @@ -77,17 +77,21 @@ static public SpecificTypeReference unify(SpecificTypeReference a, SpecificTypeR if ((a.isDynamic() || a.isExpr()) && constantIsNullValue(a) && !b.isUnknown()) return b; if ((b.isDynamic() || b.isExpr()) && constantIsNullValue(b) && !a.isUnknown()) return a; + boolean isNullWrapped = a.isNullType() || b.isNullType(); + SpecificTypeReference referenceA = a.isNullType() ? ((SpecificHaxeClassReference)a).unwrapNullType() : a; + SpecificTypeReference referenceB = b.isNullType() ? ((SpecificHaxeClassReference)b).unwrapNullType() : b; - if (a instanceof SpecificHaxeClassReference && b instanceof SpecificHaxeClassReference) { + if (referenceA instanceof SpecificHaxeClassReference classReferenceA && referenceB instanceof SpecificHaxeClassReference classReferenceB) { if (suggestedType instanceof SpecificHaxeClassReference suggestedClassReference) { - SpecificTypeReference reference = unifyTypes(suggestedClassReference, (SpecificHaxeClassReference)a, context, rules); - reference = unifyTypes((SpecificHaxeClassReference)reference, (SpecificHaxeClassReference)b, context, rules); + SpecificTypeReference reference = unifyTypes(suggestedClassReference, classReferenceA, context, rules); + reference = unifyTypes((SpecificHaxeClassReference)reference, classReferenceB, context, rules); if (!reference.isUnknown()) { return reference; } } - return unifyTypes((SpecificHaxeClassReference)a, (SpecificHaxeClassReference)b, context, rules); + SpecificTypeReference reference = unifyTypes(classReferenceA, classReferenceB, context, rules); + return isNullWrapped? reference.wrapInNullType() : reference; } if (a instanceof SpecificFunctionReference && b instanceof SpecificFunctionReference) { // TODO suggested type support for functions @@ -165,6 +169,21 @@ static public SpecificTypeReference unifyTypes(SpecificHaxeClassReference a, Spe if (a.getHaxeClassModel() == null) return SpecificTypeReference.getDynamic(context); if (b.getHaxeClassModel() == null) return SpecificTypeReference.getDynamic(context); + // if not same type but typedef, resolve typdefs and try to unify real type + if (!a.isSameType(b) && (a.isTypeDef() || b.isTypeDef())) { + SpecificTypeReference referenceA = a; + SpecificTypeReference referenceB = b; + if (a.isTypeDef()) { + referenceA = a.fullyResolveTypeDefReference(); + } + if (b.isTypeDef()) { + referenceB = b.fullyResolveTypeDefReference(); + } + if (referenceA != null && referenceB != null) { + return unify(referenceA, referenceB, context, rules); + } + } + @NotNull ResultHolder[] specificsA = a.getSpecifics(); @NotNull ResultHolder[] specificsB = b.getSpecifics(); if (a.isSameType(b)) {