diff --git a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeCallExpressionUtil.java b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeCallExpressionUtil.java index f3fda41e3..6e45831af 100644 --- a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeCallExpressionUtil.java +++ b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeCallExpressionUtil.java @@ -713,7 +713,7 @@ private static void inheritTypeParametersFromArgument(ResultHolder parameterType HaxeGenericResolver inherit = findTypeParametersToInherit(parameterType.getType(), argumentType.getType(), resolver, typeParamMap); resolver.addAll(inherit); // parameter is a typeParameter type, we can just add it to resolver - if (parameterType.getClassType().isFromTypeParameter()) { + if (parameterType.getClassType().isTypeParameter()) { String className = parameterType.getClassType().getClassName(); resolver.add(className, argumentType, ResolveSource.ARGUMENT_TYPE); typeParamMap.put(className, argumentType); diff --git a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/TypeParameterUtil.java b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/TypeParameterUtil.java index eebc184f7..7418cca27 100644 --- a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/TypeParameterUtil.java +++ b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/TypeParameterUtil.java @@ -65,7 +65,7 @@ public static Map createTypeParameterConstraintMap(List typeParamMap) { if (parameterType.getClassType() == null) return false; - if (parameterType.getClassType().isFromTypeParameter()) return true; + if (parameterType.getClassType().isTypeParameter()) return true; ResultHolder[] specifics = parameterType.getClassType().getSpecifics(); diff --git a/src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java b/src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java index d700fc0c3..60c731090 100644 --- a/src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java +++ b/src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java @@ -633,7 +633,7 @@ else if (implementOrExtendSameClass) { HaxeResolveResult result = null; HaxeGenericSpecialization specialization = getSpecialization(); if (resolvedType.getClassType() != null && !resolvedType.isUnknown()) { - if (!resolvedType.getClassType().isFromTypeParameter()) { + if (!resolvedType.getClassType().isTypeParameter()) { result = resolvedType.getClassType().asResolveResult(); if (specialization != null) { result.specializeByParent(specialization.toGenericResolver(null)); diff --git a/src/main/java/com/intellij/plugins/haxe/model/HaxeClassModel.java b/src/main/java/com/intellij/plugins/haxe/model/HaxeClassModel.java index f1f1bae26..d2acfbfbe 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeClassModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeClassModel.java @@ -299,7 +299,7 @@ public List getImplicitCastToTypesList(SpecificHaxeClassR for (HaxeMethodModel methodModel : methodsWithMetadata) { if (castMethodAcceptsSource(sourceType, methodModel)) { SpecificTypeReference returnType = getReturnType(methodModel); - if (returnType.isFromTypeParameter()) { + if (returnType.isTypeParameter()) { ResultHolder resolve = sourceType.getGenericResolver().resolve(((SpecificHaxeClassReference)returnType).getClassName()); if (resolve!= null && !resolve.isUnknown()) { returnType = resolve.getType(); diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluator.java b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluator.java index ded1a2ae8..c231bacd8 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluator.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluator.java @@ -201,7 +201,7 @@ static private ResultHolder _handle(final PsiElement element, return handle.getType().createHolder(); } } - if (type.isFromTypeParameter()) { + if (type.isTypeParameter()) { if (iterable.getExpression() instanceof HaxeReference reference) { HaxeResolveResult result = reference.resolveHaxeClass(); HaxeGenericResolver classResolver = result.getGenericResolver(); diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeGenericResolver.java b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeGenericResolver.java index c73a73003..13c7bed72 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeGenericResolver.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeGenericResolver.java @@ -161,7 +161,7 @@ private int ResolverPrioritySort(ResolverEntry entry, ResolverEntry entry1) { @Nullable public ResultHolder resolveReturnType(SpecificHaxeClassReference reference) { if (null == reference ) return null; - if (reference.isFromTypeParameter()) { + if (reference.isTypeParameter()) { String className = reference.getHaxeClassReference().name; List resolveValues = resolvers.stream().filter(entry -> entry.name().equals(className)).toList(); List constraints = constaints.stream().filter(entry -> entry.name().equals(className)).toList(); @@ -182,7 +182,7 @@ public ResultHolder resolveReturnType(SpecificHaxeClassReference reference) { } } // todo recursion guard - if (!reference.isFromTypeParameter() && needResolve(reference)) { + if (!reference.isTypeParameter() && needResolve(reference)) { return HaxeTypeResolver.resolveParameterizedType(reference.createHolder(), this, true); } return reference.createHolder(); @@ -202,7 +202,7 @@ private Optional findAsignToType() { @Nullable public ResultHolder resolveReturnType(ResultHolder resultHolder) { if (null == resultHolder ) return null; - if (resultHolder.getType().isFromTypeParameter()) { + if (resultHolder.getType().isTypeParameter()) { String className = resultHolder.getType().context.getText(); List list = resolvers.stream().filter(entry -> entry.name().equals(className)).sorted(this::ResolverPrioritySort).toList(); if (list.isEmpty()) { @@ -215,7 +215,7 @@ public ResultHolder resolveReturnType(ResultHolder resultHolder) { return list.get(0).type(); } } - if (!resultHolder.getType().isFromTypeParameter()) { + if (!resultHolder.getType().isTypeParameter()) { Optional assign = findAsignToType(); if (assign.isPresent()) { // if we got expected return type we want to pass along expected typeParameter values when resolving SpecificHaxeClassReference expectedType = assign.get().type().getClassType(); diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeCompatible.java b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeCompatible.java index 3d50b3a69..d50e5b366 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeCompatible.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeCompatible.java @@ -19,7 +19,6 @@ */ package com.intellij.plugins.haxe.model.type; -import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.plugins.haxe.lang.psi.*; import com.intellij.plugins.haxe.model.*; import com.intellij.plugins.haxe.util.HaxeResolveUtil; @@ -213,7 +212,7 @@ static public boolean canAssignToFrom( return toReference.isSameType(fromReference); } // if value is type parameter and we have reached this point without resolving its type we just accept it as it would be the same as unknown - if (to.isFromTypeParameter()) return true; + if (to.isTypeParameter()) return true; return false; @@ -439,7 +438,7 @@ static private boolean canAssignToFromType( for (SpecificHaxeClassReference compatibleType : compatibleTypes) { if (canAssignToFromSpecificType(to, compatibleType)) return true; } - if (to.isFromTypeParameter()) { + if (to.isTypeParameter()) { // if we don't know the type and don't have any constraints for Type parameters we just accept it for now // to avoid wrong error annotations return true; @@ -450,7 +449,7 @@ static private boolean canAssignToFromType( } private static boolean containsAllMembers(SpecificHaxeClassReference to, SpecificHaxeClassReference from) { - if (to.isFromTypeParameter() || from.isFromTypeParameter() ) return false; // unable to evaluate members when type is not resolved + if (to.isTypeParameter() || from.isTypeParameter() ) return false; // unable to evaluate members when type is not resolved // if one of the types is a Class its was probably wrapped so we unwrap to T if (to.isClass() && to.getSpecifics().length == 1) to = to.getSpecifics()[0].getClassType(); @@ -622,7 +621,7 @@ else if (from.getSpecifics().length == 0) { } } // if not working with type parameters check inheritance - if (!to.isFromTypeParameter() && !from.isFromTypeParameter()) { + if (!to.isTypeParameter() && !from.isTypeParameter()) { if (to.getHaxeClass() != null && to.getHaxeClass().isInterface()) { Set fromInferTypes = from.getInferTypes(); for (SpecificHaxeClassReference fromInterface : fromInferTypes) { diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeResolver.java b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeResolver.java index 76abcea36..76eb3d553 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeResolver.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeTypeResolver.java @@ -238,7 +238,7 @@ static public ResultHolder resolveParameterizedType(@NotNull ResultHolder result static public ResultHolder resolveParameterizedType(@NotNull ResultHolder result, HaxeGenericResolver resolver, boolean returnType) { SpecificTypeReference typeReference = result.getType(); if (resolver != null) { - if (typeReference instanceof SpecificHaxeClassReference haxeClassReference && typeReference.isFromTypeParameter()) { + if (typeReference instanceof SpecificHaxeClassReference haxeClassReference && typeReference.isTypeParameter()) { String className = haxeClassReference.getClassName(); ResultHolder resolved = returnType ? resolver.resolveReturnType(haxeClassReference) : resolver.resolve(className); if (null != resolved) { diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/SpecificHaxeClassReference.java b/src/main/java/com/intellij/plugins/haxe/model/type/SpecificHaxeClassReference.java index adeec87e0..21f9e71ec 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/SpecificHaxeClassReference.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/SpecificHaxeClassReference.java @@ -643,7 +643,7 @@ public static SpecificHaxeClassReference propagateGenericsToType(@Nullable Speci if (type == null) return null; if (genericResolver == null || genericResolver.isEmpty()) return type; - if (type.isFromTypeParameter()) { + if (type.isTypeParameter()) { String typeVariableName = type.getHaxeClassReference().name; ResultHolder possibleValue = isReturnType ? genericResolver.resolveReturnType(type) : genericResolver.resolve(typeVariableName); if (possibleValue != null) { diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/SpecificTypeReference.java b/src/main/java/com/intellij/plugins/haxe/model/type/SpecificTypeReference.java index 79cb8beb9..70fe61590 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/SpecificTypeReference.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/SpecificTypeReference.java @@ -29,6 +29,7 @@ import com.intellij.plugins.haxe.model.HaxeProjectModel; import com.intellij.plugins.haxe.util.HaxeProjectUtil; import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; import lombok.CustomLog; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -309,13 +310,30 @@ final public boolean isAbstractType() { } return false; } - final public boolean isFromTypeParameter() { + /** + * In some cases we can not resolve typeParameters (ex. class level typeParameters used in class members) + * We currently work around this by creating synthetic types, this method will return true if the type is + * one of these synthetic types. + */ + final public boolean isTypeParameter() { if (this instanceof SpecificHaxeClassReference specificHaxeClassReference) { return specificHaxeClassReference.getHaxeClassReference().isTypeParameter(); } return false; } + /** + * checks if type reference is from a typeParameter (ex. `Array`) + * or if its a normal reference (ex `var x = String;` or `MyType.staticMethod()`) + * + * @return is class reference from typeParameter. + */ + final public boolean isReferenceFromTypeParameter() { + //TODO cache ? + HaxeTypeParam type = PsiTreeUtil.getParentOfType(this.context, HaxeTypeParam.class); + return type != null; + } + public boolean isAnonymousType() { if (this instanceof SpecificHaxeClassReference specificHaxeClassReference) { if(specificHaxeClassReference.getHaxeClassReference().getHaxeClass() instanceof HaxeTypedefDeclaration typedefDeclaration) { @@ -495,7 +513,7 @@ public static SpecificTypeReference propagateGenericsToType(@Nullable SpecificTy if (type == null) return null; if (genericResolver == null) return type; - if (type.isFromTypeParameter() && type instanceof SpecificHaxeClassReference classReference) { + if (type.isTypeParameter() && type instanceof SpecificHaxeClassReference classReference) { String typeVariableName = classReference.getHaxeClassReference().name; ResultHolder possibleValue = isReturnType ? genericResolver.resolveReturnType(classReference) : genericResolver.resolve(typeVariableName); if (possibleValue != null) { @@ -513,7 +531,7 @@ public static SpecificTypeReference propagateGenericsToType(@Nullable SpecificTy //final SpecificTypeReference typeReference = propagateGenericsToType(specific.getClassType(), genericResolver); if (specific.getClassType() != null) { SpecificTypeReference typeReference = null; - if (!specific.getClassType().isFromTypeParameter()) { + if (!specific.getClassType().isTypeParameter()) { typeReference = propagateGenericsToType(specific.getClassType(), specific.getClassType().getGenericResolver(), isReturnType); }else { if (isReturnType) {