diff --git a/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeGenericSpecialization.java b/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeGenericSpecialization.java index 5b2fec6a2..8381c78ee 100644 --- a/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeGenericSpecialization.java +++ b/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeGenericSpecialization.java @@ -18,6 +18,7 @@ */ package com.intellij.plugins.haxe.lang.psi; +import com.intellij.plugins.haxe.lang.psi.impl.AnonymousHaxeTypeImpl; import com.intellij.plugins.haxe.model.type.*; import com.intellij.plugins.haxe.model.type.resolver.ResolveSource; import com.intellij.plugins.haxe.util.HaxeDebugUtil; @@ -163,6 +164,11 @@ public static HaxeGenericSpecialization fromGenericResolver(@Nullable PsiElement continue; } + //NOTE: AnonymousHaxeTypeImpl can be manually created and wont necessarily share the same instance + // (see, HaxeTypeParameterMultiType, HaxeClassWrapperForTypeParameter) + // we can however check if their from the same node + if (element != null && element.getNode() == context.getNode()) continue; + SpecificHaxeClassReference classType = holder.getClassType(); if (context instanceof HaxeClass haxeClass && classType != null) { HaxeGenericResolver genericResolver = classType.getGenericResolver(); 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 a2a99ee4e..97b1e09c0 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 @@ -1177,13 +1177,23 @@ public Object[] getVariants() { // if not first in chain // foo.bar.baz - final HaxeReference leftReference = HaxeResolveUtil.getLeftReference(this); HaxeResolveResult result = null; + final HaxeReference leftReference = HaxeResolveUtil.getLeftReference(this); + if (leftReference != null) { + HaxeGenericResolver resolver = HaxeGenericResolverUtil.generateResolverFromScopeParents(leftReference); + ResultHolder leftResult = HaxeTypeResolver.getPsiElementType(leftReference, resolver); + if (leftResult.getClassType() != null) { + SpecificTypeReference reference = leftResult.getClassType().fullyResolveTypeDefAndUnwrapNullTypeReference(); + result = reference.asResolveResult(); + }else { + result = leftResult.getType().asResolveResult(); + } + } + HaxeClass haxeClass = null; String name = null; HaxeGenericResolver resolver = null; - if (leftReference != null) { - result = leftReference.resolveHaxeClass(); + if (result != null) { if (result != HaxeResolveResult.EMPTY) { haxeClass = result.getHaxeClass(); if (haxeClass != null) { @@ -1207,7 +1217,7 @@ public Object[] getVariants() { addChildClassVariants(suggestedVariants, haxeClass); } - else if (leftReference != null && !result.isFunctionType()) { + else if (result != null && !result.isFunctionType()) { if (null == haxeClass) { // TODO: fix haxeClass by type inference. Use compiler code assist?! } 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 ae90976dc..63bd9f7c8 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 @@ -61,7 +61,8 @@ static public HaxeExpressionEvaluatorContext evaluate(PsiElement element, HaxeGe // evaluation of complex expressions can in some cases result in needing the type for a psiElement multiple times // untyped parameters and variables can cause a lot of unnecessary computation if we have to re-evaluate them // in order to avoid this we put any useful results in a thread-local map that we clear once we are done with the evaluation - private static final ThreadLocal> resultCache = ThreadLocal.withInitial(HashMap::new); + record CacheRecord(ResultHolder holder, String resolverAsString){} + private static final ThreadLocal> resultCache = ThreadLocal.withInitial(HashMap::new); private static final ThreadLocal> resultCacheHits = ThreadLocal.withInitial(HashMap::new); private static final ThreadLocal> processingStack = ThreadLocal.withInitial(Stack::new); @NotNull @@ -206,11 +207,11 @@ static private ResultHolder _handle(final PsiElement element, return handleValueIterator(context, resolver, valueIterator); } if (element instanceof HaxeIteratorkey || element instanceof HaxeIteratorValue) { - return resolveWithCache(element, () -> findIteratorType(element)); + return resolveWithCache(element, resolver, () -> findIteratorType(element)); } if (element instanceof HaxeEnumExtractedValue extractedValue) { - return resolveWithCache(extractedValue, () -> handleEnumExtractedValue(extractedValue)); + return resolveWithCache(extractedValue, resolver, () -> handleEnumExtractedValue(extractedValue)); } //NOTE: must be before HaxeParameter as HaxeRestParameter extends HaxeParameter @@ -221,7 +222,7 @@ static private ResultHolder _handle(final PsiElement element, if (element instanceof HaxeParameter parameter) { boolean isUntyped = parameter.getTypeTag() == null && parameter.getVarInit() == null; if (isUntyped) { - return resolveWithCache(element, () -> handleParameter(context, resolver, parameter)); + return resolveWithCache(element, resolver, () -> handleParameter(context, resolver, parameter)); } return handleParameter(context, resolver, parameter); } @@ -243,11 +244,11 @@ static private ResultHolder _handle(final PsiElement element, } if (element instanceof HaxeCallExpression callExpression) { - return resolveWithCache(callExpression, () -> handleCallExpression(context, resolver, callExpression)); + return resolveWithCache(callExpression, resolver, () -> handleCallExpression(context, resolver, callExpression)); } if (element instanceof HaxeReferenceExpression referenceExpression) { - return resolveWithCache(referenceExpression, () -> handleReferenceExpression(context, resolver, referenceExpression)); + return resolveWithCache(referenceExpression, resolver, () -> handleReferenceExpression(context, resolver, referenceExpression)); } if (element instanceof HaxeCastExpression castExpression) { @@ -314,7 +315,7 @@ static private ResultHolder _handle(final PsiElement element, } if (element instanceof HaxeFunctionLiteral function) { - return resolveWithCache(function, () -> handleFunctionLiteral(context, resolver, function)); + return resolveWithCache(function, resolver, () -> handleFunctionLiteral(context, resolver, function)); } if (element instanceof HaxePsiToken primitive) { @@ -370,12 +371,14 @@ static private ResultHolder _handle(final PsiElement element, return createUnknown(element); } - private static ResultHolder resolveWithCache(PsiElement element, Supplier resolveLogic) { - Map map = resultCache.get(); + private static ResultHolder resolveWithCache(@NotNull PsiElement element, @NotNull HaxeGenericResolver resolver, Supplier resolveLogic) { + Map map = resultCache.get(); Map hitCounter = resultCacheHits.get(); - if (map.containsKey(element)) { + String resolverAsString = resolver.toCacheString(); + if (map.containsKey(element) && map.get(element).resolverAsString().equals(resolverAsString)) { + CacheRecord cacheRecord = map.get(element); hitCounter.get(element).incrementAndGet(); - return map.get(element); + return cacheRecord.holder(); }else { ResultHolder result = resolveLogic.get(); if (!result.isUnknown()) { @@ -383,11 +386,11 @@ private static ResultHolder resolveWithCache(PsiElement element, Supplier entry.name() + ":" + entry.type().toPresentationString() + ":" + entry.resolveSource()) + .collect(Collectors.joining(",")); + String constrainsAsString = constaints.stream().map(entry -> entry.name() + ":" + entry.type().toPresentationString() + ":" + entry.resolveSource()) + .collect(Collectors.joining(",")); + return "resolvers:["+resolversAsString + "], constraints: [" + constrainsAsString+"]"; + } } diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java index bd71da639..947d34326 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java @@ -35,13 +35,9 @@ public class HaxeGenericResolverUtil { public static HaxeGenericResolver generateResolverFromScopeParents(PsiElement element) { HaxeGenericResolver resolver = new HaxeGenericResolver(); - HaxeMethod method = element instanceof HaxeMethod - ? (HaxeMethod)element - : UsefulPsiTreeUtil.getParentOfType(element, HaxeMethod.class); - boolean isStatic = null != method && method.isStatic(); - if (!isStatic) { - appendClassGenericResolver(element, resolver); - } + + appendClassGenericResolver(element, resolver); + appendMethodGenericResolver(element, resolver); appendStatementGenericResolver(HaxeResolveUtil.getLeftReference(element), resolver); appendCallExpressionGenericResolver(element, resolver);