diff --git a/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolver.java b/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolver.java index 57775f97c..db439f0cc 100644 --- a/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolver.java +++ b/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolver.java @@ -232,6 +232,7 @@ private List doResolveInner(@NotNull HaxeReference referen String currentQname = enumValueDeclaration.getContainingClass().getQualifiedName(); String data = typeHintPsi.getUserData(typeHintKey); if (currentQname != null && currentQname.equals(data)) { + LogResolution(reference, "via import & typeHintKey"); return List.of(element); } } @@ -242,6 +243,7 @@ private List doResolveInner(@NotNull HaxeReference referen int currentSize = Optional.ofNullable(enumValueDeclaration.getParameterList()).map(p -> p.getParameterList().size()).orElse(0); if (expectedSize == currentSize) { + LogResolution(reference, "via import & enum value declaration"); return List.of(element); } } @@ -277,11 +279,23 @@ private List doResolveInner(@NotNull HaxeReference referen // to avoid caching empty due to already being resolved we mark // elements so we know if we want to cache as not found or just skip (null is not cached, empty list is cached) if (reference.getUserData(skipCacheKey) == Boolean.TRUE) { + if (log.isTraceEnabled()) { + String message = "result is empty and skip cache flag is true, skipping cache for: " + referenceText; + traceAs(log, HaxeDebugUtil.getCallerStackFrame(), message); + } return null; }else { + if (log.isTraceEnabled()){ + String message = "result is empty caching not found for :" + referenceText; + traceAs(log, HaxeDebugUtil.getCallerStackFrame(), message); + } return EMPTY_LIST; } }else { + if (log.isTraceEnabled()){ + String message = "caching result for :" + referenceText; + traceAs(log, HaxeDebugUtil.getCallerStackFrame(), message); + } return result; } } @@ -357,7 +371,10 @@ private static List findEnumMember(HaxeReference reference, HaxeClass haxeClass = classReference.getHaxeClass(); if (haxeClass != null) { HaxeNamedComponent name = haxeClass.findHaxeMemberByName(reference.getText(), null); - if (name != null) return List.of(name); + if (name != null) { + LogResolution(reference, "via enum member name."); + return List.of(name); + } } } } @@ -369,7 +386,10 @@ private List checkGlobalAlias(HaxeReference reference) { if (!ApplicationManager.getApplication().isUnitTestMode()) { HaxeProjectModel haxeProjectModel = HaxeProjectModel.fromElement(reference); HaxeModel model = haxeProjectModel.getLogPackage().resolveTrace(); - if (model != null) return List.of(model.getBasePsi()); + if (model != null){ + LogResolution(reference, "via global alias"); + return List.of(model.getBasePsi()); + } } } return null; @@ -380,7 +400,10 @@ private static List searchInSameFile(@NotNull HaxeReference referenc if(fileModel != null) { String className = reference.getText(); PsiElement target = HaxeResolveUtil.searchInSameFile(fileModel, className, isType); - if (target!= null) return List.of(target); + if (target!= null) { + LogResolution(reference, "via search In Same File"); + return List.of(target); + } } return null; } @@ -482,7 +505,9 @@ private List checkEnumExtractor(HaxeReference reference) { SpecificHaxeClassReference classReference = HaxeResolveUtil.resolveExtractorEnum(argumentExtractor); if (classReference != null) { HaxeEnumValueDeclaration declaration = HaxeResolveUtil.resolveExtractorEnumValueDeclaration(classReference, argumentExtractor); - if (declaration!= null) return List.of(declaration); + if (declaration!= null) + LogResolution(reference, "via enum extractor"); + return List.of(declaration); } }else { // Last attempt to resolve enum value (not extractor), normally imports would solve this but some typedefs can omit this. @@ -496,7 +521,10 @@ private List checkEnumExtractor(HaxeReference reference) { if(haxeClass != null && haxeClass.isEnum()) { SpecificHaxeClassReference classReference = result.getSpecificClassReference(haxeClass, null); HaxeEnumValueDeclaration declaration = HaxeResolveUtil.resolveExtractorEnumValueDeclaration(classReference, reference.getText()); - if (declaration!= null) return List.of(declaration); + if (declaration!= null) { + LogResolution(reference, "via enum extractor"); + return List.of(declaration); + } } } @@ -516,6 +544,7 @@ private List checkCaptureVarReference(HaxeReference refere if (haxeExpression instanceof HaxeExtractorMatchExpression matchExpression) { HaxeExpression PossibleCapture = matchExpression.getSwitchCaseExpr().getExpression(); if (PossibleCapture != null && PossibleCapture.textMatches(reference)) { + LogResolution(reference, "via switch argument extractor"); return List.of(PossibleCapture); } } @@ -524,6 +553,7 @@ private List checkCaptureVarReference(HaxeReference refere else if (expression instanceof HaxeExtractorMatchExpression matchExpression) { HaxeReferenceExpression referenceFromExtractor = getReferenceFromExtractorMatchExpression(matchExpression); if (referenceFromExtractor!= null && reference.textMatches(referenceFromExtractor)) { + LogResolution(reference, "via witch extractor"); return List.of(referenceFromExtractor); } } @@ -557,6 +587,7 @@ private List checkCaptureVar(HaxeReference reference) { HaxeExtractorMatchExpression matchExpression = PsiTreeUtil.getParentOfType(reference, HaxeExtractorMatchExpression.class); if (matchExpression!= null) { if (matchExpression.getSwitchCaseExpr().textMatches(reference.getText())) { + LogResolution(reference, "via Capture Var"); return List.of(matchExpression.getExpression()); } } @@ -587,7 +618,9 @@ private List checkIsSwitchVar(HaxeReference reference) { // try to resolve reference for guard and block (ex. `case [a, b] if ( b > a): b + ">" + a;`) if (result == null) result = tryResolveVariableForGuardsAndBlock(reference); - + if (result != null) { + LogResolution(reference, "via switch var"); + } return result; } @@ -822,6 +855,7 @@ private List checkIsAlias(HaxeReference reference) { if (alias != null) { HaxeIdentifier identifier = alias.getIdentifier(); if (identifier.textMatches(reference)) { + LogResolution(reference, "via import alias name."); return List.of(alias); } } 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 b12d0db94..7ae2fb91f 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 @@ -148,7 +148,7 @@ public boolean isSoft() { } private List resolveNamesToParents(List nameList) { - if (log.isTraceEnabled()) log.trace(traceMsg("namelist: " + nameList.toString())); + if (log.isTraceEnabled()) log.trace(traceMsg("namelist: " + (nameList== null ? null : nameList.toString()))); if (nameList == null || nameList.isEmpty()) { return Collections.emptyList(); } @@ -625,66 +625,70 @@ else if (implementOrExtendSameClass) { // if this is the case threat as "class reference" Class //HaxeResolveResult resolveResult = resolveHaxeClass(); resolve = resolve(); - // find real type for import alias - if (resolve instanceof HaxeImportAlias alias) { - return alias.resolveHaxeClass(); - } + if (resolve != null) { + // find real type for import alias + if (resolve instanceof HaxeImportAlias alias) { + return alias.resolveHaxeClass(); + } - // Note: this is a bit of a hack for switch extractor arguments that are not named components but a reference to a reference - if (resolve instanceof HaxeReferenceExpression referenceExpression) { - PsiElement second = referenceExpression.resolve(); - if (second instanceof HaxeReference reference) { - // small attempt at guarding against recursive loop - if (reference != this) { - return reference.resolveHaxeClass(); + // Note: this is a bit of a hack for switch extractor arguments that are not named components but a reference to a reference + if (resolve instanceof HaxeReferenceExpression referenceExpression) { + PsiElement second = referenceExpression.resolve(); + if (second instanceof HaxeReference reference) { + // small attempt at guarding against recursive loop + if (reference != this) { + return reference.resolveHaxeClass(); + } } } - } - if (resolve instanceof HaxeAnonymousTypeField anonymousTypeField) { - HaxeTypeTag tag = anonymousTypeField.getTypeTag(); - ResultHolder resolvedType = HaxeTypeResolver.getTypeFromTypeTag(tag, anonymousTypeField); - HaxeResolveResult result = null; - HaxeGenericSpecialization specialization = getSpecialization(); - if (resolvedType.getClassType() != null && !resolvedType.isUnknown()) { - if (!resolvedType.getClassType().isTypeParameter()) { - result = resolvedType.getClassType().asResolveResult(); - if (specialization != null) { - result.specializeByParent(specialization.toGenericResolver(null)); + if (resolve instanceof HaxeAnonymousTypeField anonymousTypeField) { + HaxeTypeTag tag = anonymousTypeField.getTypeTag(); + ResultHolder resolvedType = HaxeTypeResolver.getTypeFromTypeTag(tag, anonymousTypeField); + HaxeResolveResult result = null; + HaxeGenericSpecialization specialization = getSpecialization(); + if (resolvedType.getClassType() != null && !resolvedType.isUnknown()) { + if (!resolvedType.getClassType().isTypeParameter()) { + result = resolvedType.getClassType().asResolveResult(); + if (specialization != null) { + result.specializeByParent(specialization.toGenericResolver(null)); + } } - }else { - if (specialization != null) { - ResultHolder resolveTypeParameter = specialization.toGenericResolver(resolve).resolve(resolvedType); - if (resolveTypeParameter != null - && !resolveTypeParameter.isUnknown() - && resolveTypeParameter.getClassType() != null - ) { - result = resolveTypeParameter.getClassType().asResolveResult(); + else { + if (specialization != null) { + ResultHolder resolveTypeParameter = specialization.toGenericResolver(resolve).resolve(resolvedType); + if (resolveTypeParameter != null + && !resolveTypeParameter.isUnknown() + && resolveTypeParameter.getClassType() != null + ) { + result = resolveTypeParameter.getClassType().asResolveResult(); + } } } - + if (result != null) return result; + } + else if (resolvedType.isFunctionType()) { + return HaxeResolveResult.create(resolvedType.getFunctionType().functionType); } - if (result != null) return result; - }else if (resolvedType.isFunctionType()) { - return HaxeResolveResult.create(resolvedType.getFunctionType().functionType); } - } - if (resolve instanceof HaxeMethodDeclaration methodDeclaration) { - //TODO mlo: try to make a Resolve result with method - //SpecificFunctionReference functionReference = SpecificFunctionReference.create(methodDeclaration.getModel()); - //return HaxeResolveResult.create(functionReference, getSpecialization()); - } - if (resolve instanceof HaxeClassDeclaration haxeClassDeclaration) { - String className = haxeClassDeclaration.getComponentName().getName(); + if (resolve instanceof HaxeMethodDeclaration methodDeclaration) { + //TODO mlo: try to make a Resolve result with method + //SpecificFunctionReference functionReference = SpecificFunctionReference.create(methodDeclaration.getModel()); + //return HaxeResolveResult.create(functionReference, getSpecialization()); + } + if (resolve instanceof HaxeClassDeclaration haxeClassDeclaration) { + String className = haxeClassDeclaration.getComponentName().getName(); - boolean isPure = isPureClassReferenceOf(className); + boolean isPure = isPureClassReferenceOf(className); - if (isPure) { - // wrap in Class<> - SpecificHaxeClassReference reference = SpecificHaxeClassReference.withoutGenerics(haxeClassDeclaration.getModel().getReference()); - SpecificHaxeClassReference aClass = - SpecificHaxeClassReference.getStdClass(CLASS, this, new ResultHolder[]{new ResultHolder(reference)}); - return aClass.asResolveResult(); + if (isPure) { + // wrap in Class<> + SpecificHaxeClassReference reference = + SpecificHaxeClassReference.withoutGenerics(haxeClassDeclaration.getModel().getReference()); + SpecificHaxeClassReference aClass = + SpecificHaxeClassReference.getStdClass(CLASS, this, new ResultHolder[]{new ResultHolder(reference)}); + return aClass.asResolveResult(); + } } } } @@ -693,197 +697,199 @@ else if (implementOrExtendSameClass) { if (resolve == null) { resolve = resolve(); } - if (isType(resolve, PsiPackage.class)) { - // Packages don't ever resolve to classes. (And they don't have children!) - return HaxeResolveResult.EMPTY; - } - if (isType(resolve, HaxeAnonymousTypeField.class)) { - HaxeAnonymousTypeField field = (HaxeAnonymousTypeField)resolve; - HaxeTypeTag typeTag = field.getTypeTag(); - if (typeTag.getTypeOrAnonymous() != null) { - HaxeTypeOrAnonymous typeOrAnonymous = typeTag.getTypeOrAnonymous(); - if (typeOrAnonymous != null) { - if (typeOrAnonymous.getAnonymousType() != null) { - return HaxeResolveResult.create(typeOrAnonymous.getAnonymousType(), getSpecialization()); - } - else { - HaxeType type = typeOrAnonymous.getType(); - if (type != null) { - PsiElement resolvedType = type.getReferenceExpression().resolve(); - if (resolvedType instanceof HaxeGenericListPart genericListPart) { - final HaxeComponentName componentName = genericListPart.getComponentName(); - final HaxeGenericSpecialization specialization = getSpecialization(); - if (specialization != null && componentName != null) { - String genericName = componentName.getText(); - final HaxeResolveResult result = specialization.get(resolve, genericName); - if (result != null) { - return result; + if (resolve != null) { + + if (isType(resolve, PsiPackage.class)) { + // Packages don't ever resolve to classes. (And they don't have children!) + return HaxeResolveResult.EMPTY; + } + if (isType(resolve, HaxeAnonymousTypeField.class)) { + HaxeAnonymousTypeField field = (HaxeAnonymousTypeField)resolve; + HaxeTypeTag typeTag = field.getTypeTag(); + if (typeTag.getTypeOrAnonymous() != null) { + HaxeTypeOrAnonymous typeOrAnonymous = typeTag.getTypeOrAnonymous(); + if (typeOrAnonymous != null) { + if (typeOrAnonymous.getAnonymousType() != null) { + return HaxeResolveResult.create(typeOrAnonymous.getAnonymousType(), getSpecialization()); + } + else { + HaxeType type = typeOrAnonymous.getType(); + if (type != null) { + PsiElement resolvedType = type.getReferenceExpression().resolve(); + if (resolvedType instanceof HaxeGenericListPart genericListPart) { + final HaxeComponentName componentName = genericListPart.getComponentName(); + final HaxeGenericSpecialization specialization = getSpecialization(); + if (specialization != null && componentName != null) { + String genericName = componentName.getText(); + final HaxeResolveResult result = specialization.get(resolve, genericName); + if (result != null) { + return result; + } } } - } - if (resolvedType instanceof HaxeClass) { - return HaxeResolveResult.create((HaxeClass)resolvedType, getSpecialization()); + if (resolvedType instanceof HaxeClass) { + return HaxeResolveResult.create((HaxeClass)resolvedType, getSpecialization()); + } } } } } + return HaxeResolveResult.create(HaxeResolveUtil.findClassByQName("Dynamic", this)); } - return HaxeResolveResult.create(HaxeResolveUtil.findClassByQName("Dynamic", this)); - } - - if (isType(resolve, HaxeGenericListPart.class)) { - final HaxeComponentName componentName = ((HaxeGenericListPart)resolve).getComponentName(); - if (componentName != null) { - HaxeGenericSpecialization innerSpecialization = - tryGetLeftResolveResult(this).getSpecialization(); - String genericName = componentName.getText(); - final HaxeResolveResult result = innerSpecialization.get(resolve, genericName); - if (result != null) { - return result; + + if (isType(resolve, HaxeGenericListPart.class)) { + final HaxeComponentName componentName = ((HaxeGenericListPart)resolve).getComponentName(); + if (componentName != null) { + HaxeGenericSpecialization innerSpecialization = + tryGetLeftResolveResult(this).getSpecialization(); + String genericName = componentName.getText(); + final HaxeResolveResult result = innerSpecialization.get(resolve, genericName); + if (result != null) { + return result; + } } } - } - if (isType(resolve, HaxeEnumValueDeclaration.class)) { - final HaxeEnumDeclaration enumDeclaration = UsefulPsiTreeUtil.getParentOfType(resolve, HaxeEnumDeclaration.class); - return HaxeResolveResult.create(enumDeclaration, getSpecialization()); - } + if (isType(resolve, HaxeEnumValueDeclaration.class)) { + final HaxeEnumDeclaration enumDeclaration = UsefulPsiTreeUtil.getParentOfType(resolve, HaxeEnumDeclaration.class); + return HaxeResolveResult.create(enumDeclaration, getSpecialization()); + } - if (isType(resolve, HaxeClass.class) || isType(resolve, HaxeFunctionLiteral.class)) { - // Classes (particularly typedefs) that are already resolved should not be - // re-resolved to their component parts. - return HaxeResolveResult.create((HaxeClass)resolve, getSpecialization()); - } + if (isType(resolve, HaxeClass.class) || isType(resolve, HaxeFunctionLiteral.class)) { + // Classes (particularly typedefs) that are already resolved should not be + // re-resolved to their component parts. + return HaxeResolveResult.create((HaxeClass)resolve, getSpecialization()); + } - if (isType(resolve, HaxeMethod.class)) { - // If the resolved element is a method, but the reference's parent is not a call expression, then - // we want to return the method type, and not the method's return type. (e.g. String->String->Void, rather than Void.) - List typeList = UsefulPsiTreeUtil.getPathToParentOfType(this, HaxeCallExpression.class); - if (null == typeList || typeList.size() != 1) { + if (isType(resolve, HaxeMethod.class)) { + // If the resolved element is a method, but the reference's parent is not a call expression, then + // we want to return the method type, and not the method's return type. (e.g. String->String->Void, rather than Void.) + List typeList = UsefulPsiTreeUtil.getPathToParentOfType(this, HaxeCallExpression.class); + if (null == typeList || typeList.size() != 1) { - HaxeGenericSpecialization specialization = getSpecialization(); - if (null == specialization) { - specialization = new HaxeGenericSpecialization(); - } - //failsafe check that we can get function model from SDK - if (SpecificTypeReference.getFunction(resolve).getHaxeClass() != null) { - final HaxeClass fn = new HaxeSpecificFunction((HaxeMethod)resolve, specialization); - return HaxeResolveResult.create(fn, specialization); + HaxeGenericSpecialization specialization = getSpecialization(); + if (null == specialization) { + specialization = new HaxeGenericSpecialization(); + } + //failsafe check that we can get function model from SDK + if (SpecificTypeReference.getFunction(resolve).getHaxeClass() != null) { + final HaxeClass fn = new HaxeSpecificFunction((HaxeMethod)resolve, specialization); + return HaxeResolveResult.create(fn, specialization); + } } } - } - if (isType(resolve, HaxeEnumExtractedValue.class)) { - HaxeEnumExtractedValue extractedValue = (HaxeEnumExtractedValue)resolve; - HaxeEnumArgumentExtractor extractor = PsiTreeUtil.getParentOfType(extractedValue, HaxeEnumArgumentExtractor.class); - if (extractor != null) { - int index = -1; - @NotNull PsiElement[] children = extractor.getEnumExtractorArgumentList().getChildren(); - for (int i = 0; i < children.length; i++) { - if (children[i] == resolve) { - index = i; - break; + if (isType(resolve, HaxeEnumExtractedValue.class)) { + HaxeEnumExtractedValue extractedValue = (HaxeEnumExtractedValue)resolve; + HaxeEnumArgumentExtractor extractor = PsiTreeUtil.getParentOfType(extractedValue, HaxeEnumArgumentExtractor.class); + if (extractor != null) { + int index = -1; + @NotNull PsiElement[] children = extractor.getEnumExtractorArgumentList().getChildren(); + for (int i = 0; i < children.length; i++) { + if (children[i] == resolve) { + index = i; + break; + } } - } - SpecificHaxeClassReference enumClass = HaxeResolveUtil.resolveExtractorEnum(extractor); - HaxeEnumValueDeclaration enumValueDeclaration = HaxeResolveUtil.resolveExtractorEnumValueDeclaration(enumClass, extractor); - if (enumValueDeclaration != null) { - HaxeParameter parameter = enumValueDeclaration.getParameterList().getParameterList().get(index); - HaxeGenericResolver resolver = enumClass.getGenericResolver(); - ResultHolder type = HaxeTypeResolver.getPsiElementType(parameter, resolver); - ResultHolder resultHolder = resolver.resolve(type); - if(resultHolder != null && resultHolder.getClassType()!= null) { - return resultHolder.getClassType().asResolveResult(); + SpecificHaxeClassReference enumClass = HaxeResolveUtil.resolveExtractorEnum(extractor); + HaxeEnumValueDeclaration enumValueDeclaration = HaxeResolveUtil.resolveExtractorEnumValueDeclaration(enumClass, extractor); + if (enumValueDeclaration != null) { + HaxeParameter parameter = enumValueDeclaration.getParameterList().getParameterList().get(index); + HaxeGenericResolver resolver = enumClass.getGenericResolver(); + ResultHolder type = HaxeTypeResolver.getPsiElementType(parameter, resolver); + ResultHolder resultHolder = resolver.resolve(type); + if(resultHolder != null && resultHolder.getClassType()!= null) { + return resultHolder.getClassType().asResolveResult(); + } } } } - } - // RestParameter can have a normal typeTag but the argument is treated as an array, so we have to wrap it in an array - if (isType(resolve, HaxeRestParameter.class)) { - HaxeTypeTag tag = ((HaxeParameter)resolve).getTypeTag(); - ResultHolder type = HaxeTypeResolver.getTypeFromTypeTag(tag, resolve); - return SpecificTypeReference.getStdClass(ARRAY, resolve, new ResultHolder[]{type}).asResolveResult(); - } - if (isType(resolve, HaxeParameter.class)) { - // check if type parameters has multiple constraints and try to unify - HaxeTypeTag tag = ((HaxeParameter)resolve).getTypeTag(); - String typeName = tag != null && tag.getTypeOrAnonymous() != null ? tag.getTypeOrAnonymous().getText() : null; - PsiElement parameterList = resolve.getParent(); - - if (parameterList != null && parameterList.getParent() instanceof HaxeMethodDeclaration) { - HaxeMethodDeclaration method = (HaxeMethodDeclaration)parameterList.getParent(); - HaxeGenericParam methodGenericParam = method.getGenericParam(); - List methodPartList = methodGenericParam != null ? methodGenericParam.getGenericListPartList() : null; - - List classPartList = null; - if (method.getContainingClass() instanceof HaxeClassDeclaration declaringClass) { - // check class for type parameters - HaxeGenericParam classGenericParam = declaringClass.getGenericParam(); - classPartList = classGenericParam != null ? classGenericParam.getGenericListPartList() : null; - } + // RestParameter can have a normal typeTag but the argument is treated as an array, so we have to wrap it in an array + if (isType(resolve, HaxeRestParameter.class)) { + HaxeTypeTag tag = ((HaxeParameter)resolve).getTypeTag(); + ResultHolder type = HaxeTypeResolver.getTypeFromTypeTag(tag, resolve); + return SpecificTypeReference.getStdClass(ARRAY, resolve, new ResultHolder[]{type}).asResolveResult(); + } + if (isType(resolve, HaxeParameter.class)) { + // check if type parameters has multiple constraints and try to unify + HaxeTypeTag tag = ((HaxeParameter)resolve).getTypeTag(); + String typeName = tag != null && tag.getTypeOrAnonymous() != null ? tag.getTypeOrAnonymous().getText() : null; + PsiElement parameterList = resolve.getParent(); + + if (parameterList != null && parameterList.getParent() instanceof HaxeMethodDeclaration) { + HaxeMethodDeclaration method = (HaxeMethodDeclaration)parameterList.getParent(); + HaxeGenericParam methodGenericParam = method.getGenericParam(); + List methodPartList = methodGenericParam != null ? methodGenericParam.getGenericListPartList() : null; + + List classPartList = null; + if (method.getContainingClass() instanceof HaxeClassDeclaration declaringClass) { + // check class for type parameters + HaxeGenericParam classGenericParam = declaringClass.getGenericParam(); + classPartList = classGenericParam != null ? classGenericParam.getGenericListPartList() : null; + } - if (methodPartList != null || classPartList != null) { - HaxeGenericListPart listPart = null; - // check method declaration first if it got generic params - if (methodPartList != null) { - for (HaxeGenericListPart genericListPart : methodPartList) { - if (Objects.equals(typeName, genericListPart.getName())) { - listPart = genericListPart; - break; + if (methodPartList != null || classPartList != null) { + HaxeGenericListPart listPart = null; + // check method declaration first if it got generic params + if (methodPartList != null) { + for (HaxeGenericListPart genericListPart : methodPartList) { + if (Objects.equals(typeName, genericListPart.getName())) { + listPart = genericListPart; + break; + } } } - } - // if not found in method, then check class - if (listPart == null && classPartList != null) { - for (HaxeGenericListPart genericListPart : classPartList) { - if (Objects.equals(typeName, genericListPart.getName())) { - listPart = genericListPart; - break; + // if not found in method, then check class + if (listPart == null && classPartList != null) { + for (HaxeGenericListPart genericListPart : classPartList) { + if (Objects.equals(typeName, genericListPart.getName())) { + listPart = genericListPart; + break; + } } } - } - if (listPart != null) { - HaxeTypeList list = listPart.getTypeList(); - HaxeTypeListPart typeListPart = listPart.getTypeListPart(); - ASTNode node = listPart.getContext().getNode(); - if (list != null) { - List classReferences = new ArrayList<>(); - for (HaxeTypeListPart part : list.getTypeListPartList()) { - HaxeType type = part.getTypeOrAnonymous() == null ? null : part.getTypeOrAnonymous().getType(); - if (type != null) { - classReferences.add(type); + if (listPart != null) { + HaxeTypeList list = listPart.getTypeList(); + HaxeTypeListPart typeListPart = listPart.getTypeListPart(); + ASTNode node = listPart.getContext().getNode(); + if (list != null) { + List classReferences = new ArrayList<>(); + for (HaxeTypeListPart part : list.getTypeListPartList()) { + HaxeType type = part.getTypeOrAnonymous() == null ? null : part.getTypeOrAnonymous().getType(); + if (type != null) { + classReferences.add(type); + } } - } - HaxeTypeParameterMultiType constraint = HaxeTypeParameterMultiType.withTypeList(node, classReferences); - return HaxeResolveResult.create(constraint); - }else if (typeListPart != null) { - HaxeTypeOrAnonymous typeOrAnonymous = typeListPart.getTypeOrAnonymous(); - if (typeOrAnonymous != null) { - if (typeOrAnonymous.getType() != null) { - HaxeTypeParameterMultiType constraint = - HaxeTypeParameterMultiType.withTypeList(node, List.of(typeOrAnonymous.getType())); + HaxeTypeParameterMultiType constraint = HaxeTypeParameterMultiType.withTypeList(node, classReferences); + return HaxeResolveResult.create(constraint); + }else if (typeListPart != null) { + HaxeTypeOrAnonymous typeOrAnonymous = typeListPart.getTypeOrAnonymous(); + if (typeOrAnonymous != null) { + if (typeOrAnonymous.getType() != null) { + HaxeTypeParameterMultiType constraint = + HaxeTypeParameterMultiType.withTypeList(node, List.of(typeOrAnonymous.getType())); - return HaxeResolveResult.create(constraint); - } - else if (typeOrAnonymous.getAnonymousType() != null) { - HaxeAnonymousType anonymousType = typeOrAnonymous.getAnonymousType(); - HaxeTypeParameterMultiType constraint = - HaxeTypeParameterMultiType.withAnonymousList(node, anonymousType.getAnonymousTypeBodyList()); + return HaxeResolveResult.create(constraint); + } + else if (typeOrAnonymous.getAnonymousType() != null) { + HaxeAnonymousType anonymousType = typeOrAnonymous.getAnonymousType(); + HaxeTypeParameterMultiType constraint = + HaxeTypeParameterMultiType.withAnonymousList(node, anonymousType.getAnonymousTypeBodyList()); - return HaxeResolveResult.create(constraint); + return HaxeResolveResult.create(constraint); + } } } } } - } - else { + else { + } } } - } - if (resolve != null) { + return HaxeResolveUtil.getHaxeClassResolveResult(resolve, getSpecialization()); } diff --git a/src/main/java/com/intellij/plugins/haxe/util/HaxeDebugLogUtil.java b/src/main/java/com/intellij/plugins/haxe/util/HaxeDebugLogUtil.java index 8e5d80437..08324bbec 100644 --- a/src/main/java/com/intellij/plugins/haxe/util/HaxeDebugLogUtil.java +++ b/src/main/java/com/intellij/plugins/haxe/util/HaxeDebugLogUtil.java @@ -29,7 +29,7 @@ public class HaxeDebugLogUtil { return com.intellij.openapi.diagnostic.Logger.getInstance(clazz); } public static void traceAs(Logger logger, StackTraceElement frame, Object message) { - traceAs(logger, frame, message); + traceAs(logger, frame, message, null); } public static void traceAs(Logger logger, StackTraceElement frame, Object message, Throwable t) {