From 9cd3b563c0816884772ee9667dd2477264600baf Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Mon, 11 Jan 2021 23:02:35 +0100 Subject: [PATCH 1/3] Skip the Null "scope" for resolvers when resolving forwarded members. --- .../plugins/haxe/ide/HaxeLookupElement.java | 7 +++ .../haxe/lang/psi/impl/HaxeReferenceImpl.java | 45 ++++++++++--------- .../model/type/HaxeExpressionEvaluator.java | 6 +-- .../model/type/HaxeGenericResolverUtil.java | 18 ++++++++ .../haxe/util/HaxeAbstractForwardUtil.java | 6 ++- 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/common/com/intellij/plugins/haxe/ide/HaxeLookupElement.java b/src/common/com/intellij/plugins/haxe/ide/HaxeLookupElement.java index ca676c1dd..57d78593a 100644 --- a/src/common/com/intellij/plugins/haxe/ide/HaxeLookupElement.java +++ b/src/common/com/intellij/plugins/haxe/ide/HaxeLookupElement.java @@ -33,12 +33,15 @@ import com.intellij.plugins.haxe.model.HaxeBaseMemberModel; import com.intellij.plugins.haxe.model.HaxeMethodContext; import com.intellij.plugins.haxe.model.HaxeMethodModel; +import com.intellij.plugins.haxe.model.type.HaxeGenericResolver; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import static com.intellij.plugins.haxe.model.type.HaxeGenericResolverUtil.getResolverSkipAbstractNullScope; + /** * @author: Fedor.Korotkov */ @@ -82,6 +85,10 @@ public void renderElement(LookupElementPresentation presentation) { presentation.setItemText(getLookupString()); return; } + HaxeGenericResolver resolver = null; + if(leftReference != null && leftReference.getHaxeClass() != null) { + resolver = getResolverSkipAbstractNullScope(leftReference.getHaxeClass().getModel(), leftReference.getGenericResolver()); + } String presentableText = myComponentNamePresentation.getPresentableText(); diff --git a/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java b/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java index 05fc85780..64a9344c4 100644 --- a/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java +++ b/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java @@ -51,6 +51,7 @@ import java.util.stream.Collectors; import static com.intellij.openapi.util.text.StringUtil.defaultIfEmpty; +import static com.intellij.plugins.haxe.model.type.SpecificTypeReference.*; abstract public class HaxeReferenceImpl extends HaxeExpressionImpl implements HaxeReference { @@ -485,7 +486,13 @@ private HaxeClassResolveResult resolveHaxeClassInternal() { if (expression instanceof HaxeReference) { // creating a resolver that combines parent(leftExpression) current(expression) and children (parameterExpressions) HaxeGenericResolver resolver = new HaxeGenericResolver(); - resolver.addAll(leftResult.getGenericResolver()); + + if(leftResult.getHaxeClass() != null) { + resolver.addAll(HaxeGenericResolverUtil + .getResolverSkipAbstractNullScope(leftResult.getHaxeClass().getModel(), leftResult.getGenericResolver())); + }else { + resolver.addAll(leftResult.getGenericResolver()); + } PsiElement resolvedExpression = ((HaxeReference)expression).resolve(); if (resolvedExpression instanceof HaxeMethod) { @@ -614,29 +621,27 @@ private HaxeClassResolveResult resolveHaxeClassInternal() { 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().getText() : null; + 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(); - if(method != null) { - HaxeGenericParam genericParam = method.getGenericParam(); - List partList =genericParam != null ? genericParam.getGenericListPartList() : null; - if(partList!= null) { - Optional match = partList.stream().filter(part -> Objects.equals(typeName, part.getName())).findFirst(); - if(match.isPresent()) { - HaxeGenericListPart listPart = match.get(); - HaxeTypeList list = listPart.getTypeList(); - if(list != null) { - list.getTypeListPartList(); - List classReferences = list.getTypeListPartList().stream() - .map(part -> part.getTypeOrAnonymous() == null ? null : part.getTypeOrAnonymous().getType()) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - - HaxeTypeParameterMultiType constraint = new HaxeTypeParameterMultiType(listPart.getContext().getNode(), classReferences); - return HaxeClassResolveResult.create(constraint); - } + HaxeGenericParam genericParam = method.getGenericParam(); + List partList =genericParam != null ? genericParam.getGenericListPartList() : null; + if(partList!= null) { + Optional match = partList.stream().filter(part -> Objects.equals(typeName, part.getName())).findFirst(); + if(match.isPresent()) { + HaxeGenericListPart listPart = match.get(); + HaxeTypeList list = listPart.getTypeList(); + if(list != null) { + list.getTypeListPartList(); + List classReferences = list.getTypeListPartList().stream() + .map(part -> part.getTypeOrAnonymous() == null ? null : part.getTypeOrAnonymous().getType()) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + HaxeTypeParameterMultiType constraint = new HaxeTypeParameterMultiType(listPart.getContext().getNode(), classReferences); + return HaxeClassResolveResult.create(constraint); } } } diff --git a/src/common/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluator.java b/src/common/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluator.java index 51bc72bd9..f6badf69a 100644 --- a/src/common/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluator.java +++ b/src/common/com/intellij/plugins/haxe/model/type/HaxeExpressionEvaluator.java @@ -304,7 +304,7 @@ public void run() { ResultHolder result = typeTag != null ? typeTagResult : initResult; - if (init != null) { + if (init != null && typeTag != null) { if (!typeTagResult.canAssign(initResult)) { context.addError( element, @@ -315,9 +315,7 @@ public void run() { } } - if (name != null) { - context.setLocal(name.getText(), result); - } + context.setLocal(name.getText(), result); return result; } diff --git a/src/common/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java b/src/common/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java index 4c6e62dbb..f8700899e 100644 --- a/src/common/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java +++ b/src/common/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java @@ -16,6 +16,7 @@ package com.intellij.plugins.haxe.model.type; import com.intellij.plugins.haxe.lang.psi.*; +import com.intellij.plugins.haxe.model.HaxeAbstractClassModel; import com.intellij.plugins.haxe.model.HaxeClassModel; import com.intellij.plugins.haxe.model.HaxeMethodModel; import com.intellij.plugins.haxe.model.HaxeParameterModel; @@ -98,6 +99,9 @@ public static HaxeGenericResolver generateResolverForSupers(HaxeClass clazz) { if (element instanceof HaxeReference) { HaxeClassResolveResult result = ((HaxeReference)element).resolveHaxeClass(); resolver.addAll(result.getGenericResolver()); + if (result.getHaxeClass() != null) { + resolver.addAll(getResolverSkipAbstractNullScope(result.getHaxeClass().getModel(), result.getGenericResolver())); + } } return resolver; } @@ -177,4 +181,18 @@ public static HaxeGenericResolver generateResolverForSupers(HaxeClass clazz) { return resolver; } + // Hack? + // Since null references in some places are handled as if they where type T + // we also have to support resolving Type Parameters as if Null was just T + public static HaxeGenericResolver getResolverSkipAbstractNullScope(@Nullable HaxeClassModel model, @NotNull HaxeGenericResolver resolver) { + if (model instanceof HaxeAbstractClassModel) { + HaxeAbstractClassModel abstractClassModel = (HaxeAbstractClassModel)model; + if ("Null".equals(abstractClassModel.getName()) && abstractClassModel.isCoreType()) { + HaxeGenericListPart generic = abstractClassModel.getAbstractClass().getGenericParam().getGenericListPartList().get(0); + ResultHolder resolve = resolver.resolve(generic.getName()); + return resolve == null || resolve.getClassType() == null ? resolver : resolve.getClassType().getGenericResolver(); + } + } + return resolver; + } } diff --git a/src/common/com/intellij/plugins/haxe/util/HaxeAbstractForwardUtil.java b/src/common/com/intellij/plugins/haxe/util/HaxeAbstractForwardUtil.java index 8c5da526f..6c30b80c9 100644 --- a/src/common/com/intellij/plugins/haxe/util/HaxeAbstractForwardUtil.java +++ b/src/common/com/intellij/plugins/haxe/util/HaxeAbstractForwardUtil.java @@ -38,6 +38,8 @@ import java.util.List; import java.util.Set; +import static com.intellij.plugins.haxe.model.type.HaxeGenericResolverUtil.getResolverSkipAbstractNullScope; + /** * Extensions for resolving and analyzing @:forward abstract meta */ @@ -56,7 +58,9 @@ public static List findAbstractForwardingNamedSubComponents( final HaxeClass underlyingClass = abstractClassModel.getUnderlyingClass(resolver); if (underlyingClass != null) { if (forwardingFieldsNames.isEmpty()) { - return HaxeResolveUtil.findNamedSubComponents(resolver, underlyingClass); + HaxeGenericResolver forwardResolver = resolver != null ? resolver : new HaxeGenericResolver(); + forwardResolver = getResolverSkipAbstractNullScope(abstractClassModel, forwardResolver); + return HaxeResolveUtil.findNamedSubComponents(forwardResolver, underlyingClass); } List haxeNamedComponentList = new ArrayList<>(); for (String fieldName : forwardingFieldsNames) { From 0836de9bfba6ad30f8917b43905e60b6e8bb7dd9 Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Mon, 15 Feb 2021 21:19:41 +0100 Subject: [PATCH 2/3] formatting, replaced stream and added null safety --- .../haxe/lang/psi/impl/HaxeReferenceImpl.java | 16 ++++++++++------ .../haxe/model/type/HaxeGenericResolverUtil.java | 9 ++++++--- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java b/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java index 64a9344c4..fb72e942c 100644 --- a/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java +++ b/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java @@ -51,7 +51,6 @@ import java.util.stream.Collectors; import static com.intellij.openapi.util.text.StringUtil.defaultIfEmpty; -import static com.intellij.plugins.haxe.model.type.SpecificTypeReference.*; abstract public class HaxeReferenceImpl extends HaxeExpressionImpl implements HaxeReference { @@ -487,10 +486,10 @@ private HaxeClassResolveResult resolveHaxeClassInternal() { // creating a resolver that combines parent(leftExpression) current(expression) and children (parameterExpressions) HaxeGenericResolver resolver = new HaxeGenericResolver(); - if(leftResult.getHaxeClass() != null) { + if (leftResult.getHaxeClass() != null) { resolver.addAll(HaxeGenericResolverUtil .getResolverSkipAbstractNullScope(leftResult.getHaxeClass().getModel(), leftResult.getGenericResolver())); - }else { + } else { resolver.addAll(leftResult.getGenericResolver()); } PsiElement resolvedExpression = ((HaxeReference)expression).resolve(); @@ -629,9 +628,14 @@ private HaxeClassResolveResult resolveHaxeClassInternal() { HaxeGenericParam genericParam = method.getGenericParam(); List partList =genericParam != null ? genericParam.getGenericListPartList() : null; if(partList!= null) { - Optional match = partList.stream().filter(part -> Objects.equals(typeName, part.getName())).findFirst(); - if(match.isPresent()) { - HaxeGenericListPart listPart = match.get(); + HaxeGenericListPart listPart = null; + for (HaxeGenericListPart genericListPart : partList) { + if (Objects.equals(typeName, genericListPart.getName())) { + listPart = genericListPart; + break; + } + } + if(listPart!= null) { HaxeTypeList list = listPart.getTypeList(); if(list != null) { list.getTypeListPartList(); diff --git a/src/common/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java b/src/common/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java index f8700899e..a3461ab1a 100644 --- a/src/common/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java +++ b/src/common/com/intellij/plugins/haxe/model/type/HaxeGenericResolverUtil.java @@ -188,9 +188,12 @@ public static HaxeGenericResolver getResolverSkipAbstractNullScope(@Nullable H if (model instanceof HaxeAbstractClassModel) { HaxeAbstractClassModel abstractClassModel = (HaxeAbstractClassModel)model; if ("Null".equals(abstractClassModel.getName()) && abstractClassModel.isCoreType()) { - HaxeGenericListPart generic = abstractClassModel.getAbstractClass().getGenericParam().getGenericListPartList().get(0); - ResultHolder resolve = resolver.resolve(generic.getName()); - return resolve == null || resolve.getClassType() == null ? resolver : resolve.getClassType().getGenericResolver(); + HaxeGenericParam param = abstractClassModel.getAbstractClass().getGenericParam(); + if (param != null) { + HaxeGenericListPart generic = param.getGenericListPartList().get(0); + ResultHolder resolve = resolver.resolve(generic.getName()); + return resolve == null || resolve.getClassType() == null ? resolver : resolve.getClassType().getGenericResolver(); + } } } return resolver; From 73d921c32058dd5ebe6e9a651e70c30172f5f353 Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Tue, 16 Feb 2021 21:17:28 +0100 Subject: [PATCH 3/3] Convert stream to for-loop --- .../plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java b/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java index fb72e942c..2111fdb53 100644 --- a/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java +++ b/src/common/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java @@ -639,10 +639,13 @@ private HaxeClassResolveResult resolveHaxeClassInternal() { HaxeTypeList list = listPart.getTypeList(); if(list != null) { list.getTypeListPartList(); - List classReferences = list.getTypeListPartList().stream() - .map(part -> part.getTypeOrAnonymous() == null ? null : part.getTypeOrAnonymous().getType()) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + 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 = new HaxeTypeParameterMultiType(listPart.getContext().getNode(), classReferences); return HaxeClassResolveResult.create(constraint);