Skip to content

Commit

Permalink
filtering out Enum values if completion is on non-enum reference.
Browse files Browse the repository at this point in the history
fixing resolve for typeParameter multiType fields and methods.
attempt at caching multiType objects as userData in PsiElement
  • Loading branch information
m0rkeulv committed Apr 5, 2024
1 parent a712600 commit b752e9b
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ else if (result != null && !result.isFunctionType()) {
}
if (haxeClass != null) {
boolean isSuper = leftReference instanceof HaxeSuperExpression;
addClassNonStaticMembersVariants(suggestedVariants, haxeClass, resolver, !(isThis || isSuper));
addClassNonStaticMembersVariants(suggestedVariants, haxeClass, leftReference, resolver, !(isThis || isSuper));
addUsingVariants(suggestedVariants, suggestedVariantsExtensions, haxeClass, this);
}
}
Expand Down Expand Up @@ -1388,9 +1388,10 @@ private static void addClassStaticMembersVariants(@NotNull final Set<HaxeCompone

private void addClassNonStaticMembersVariants(Set<HaxeComponentName> suggestedVariants,
@Nullable HaxeClass haxeClass,
@Nullable HaxeReference reference,
@Nullable HaxeGenericResolver resolver,
boolean filterByAccess) {
if (haxeClass == null) {
if (haxeClass == null || reference == null) {
return;
}

Expand Down Expand Up @@ -1421,8 +1422,13 @@ private void addClassNonStaticMembersVariants(Set<HaxeComponentName> suggestedVa
if (isAbstractEnum && HaxeAbstractEnumUtil.couldBeAbstractEnumField(namedComponent)) {
continue;
}
boolean ifEnumIsClassReference = true;
if (haxeClass.isEnum() && !haxeClass.isAbstractType()) {
ifEnumIsClassReference = (reference.resolve() instanceof HaxeClass);
}
if ((extern || !needFilter) &&
!namedComponent.isStatic() &&
ifEnumIsClassReference &&
namedComponent.getComponentName() != null &&
!isConstructor(namedComponent)) {
suggestedVariants.add(namedComponent.getComponentName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
package com.intellij.plugins.haxe.lang.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Key;
import com.intellij.plugins.haxe.lang.psi.HaxeAnonymousTypeBody;
import com.intellij.plugins.haxe.lang.psi.HaxeGenericParam;
import com.intellij.plugins.haxe.lang.psi.HaxeType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Objects;
Expand All @@ -36,17 +38,30 @@
*/
public class HaxeTypeParameterMultiType extends AnonymousHaxeTypeImpl {

private static final Key<HaxeTypeParameterMultiType> ParameterMultiTypeKey = Key.create("parameterMultiType");
private final List<HaxeType> typeList;
private final List<HaxeAnonymousTypeBody> anonymousTypeBodyList;

public static HaxeTypeParameterMultiType withTypeList(@NotNull ASTNode node, @NotNull List<HaxeType> typeList) {
return new HaxeTypeParameterMultiType(node, typeList, null);
return withCached(node, typeList, null);
}
public static HaxeTypeParameterMultiType withAnonymousList(@NotNull ASTNode node, @NotNull List<HaxeAnonymousTypeBody> anonymousTypeBodyList) {
return new HaxeTypeParameterMultiType(node, null, anonymousTypeBodyList);
return withCached(node, null, anonymousTypeBodyList);
}
public static HaxeTypeParameterMultiType withTypeAndAnonymousList(@NotNull ASTNode node, @NotNull List<HaxeType> typeList, @NotNull List<HaxeAnonymousTypeBody> anonymousTypeBodyList) {
return withCached(node, typeList, anonymousTypeBodyList);
}
private static HaxeTypeParameterMultiType withCached(@NotNull ASTNode node, @Nullable List<HaxeType> typeList, @Nullable List<HaxeAnonymousTypeBody> anonymousTypeBodyList) {
HaxeTypeParameterMultiType data = node.getUserData(ParameterMultiTypeKey);
if (data != null) {
return data;
}
data = new HaxeTypeParameterMultiType(node, typeList, anonymousTypeBodyList);
node.putUserData(ParameterMultiTypeKey, data);
return data;
}

public HaxeTypeParameterMultiType(@NotNull ASTNode node, List<HaxeType> typeList, List<HaxeAnonymousTypeBody> anonymousTypeBodyList) {
private HaxeTypeParameterMultiType(@NotNull ASTNode node, List<HaxeType> typeList, List<HaxeAnonymousTypeBody> anonymousTypeBodyList) {
super(node);
this.typeList = typeList != null ? typeList : List.of();
this.anonymousTypeBodyList = anonymousTypeBodyList != null ? anonymousTypeBodyList : List.of();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.intellij.plugins.haxe.model;

import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.plugins.haxe.model.type.HaxeGenericResolver;
import com.intellij.plugins.haxe.model.type.HaxeTypeResolver;
import com.intellij.plugins.haxe.model.type.ResultHolder;
import com.intellij.plugins.haxe.model.type.SpecificHaxeClassReference;
import com.intellij.plugins.haxe.model.type.*;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiTreeUtil;
import lombok.val;
Expand Down Expand Up @@ -62,12 +59,7 @@ private List<HaxeAnonymousTypeBody> getAnonymousTypeBodyList() {

@Override
public List<HaxeFieldModel> getFields() {
List<HaxeFieldModel> inheritedFields = getCompositeTypes().stream()
.map(ResultHolder::getClassType).filter(Objects::nonNull)
.filter(SpecificHaxeClassReference::isTypeDefOfClass)
.map(classReference -> classReference.resolveTypeDefClass().getHaxeClassModel().getFields())
.flatMap(Collection::stream)
.toList();
List<HaxeFieldModel> inheritedFields = getInheritedFields();

List<HaxeFieldModel> bodyFieldList = getAnonymousTypeBodyList().stream()
.map(this::getFieldsFromBody)
Expand All @@ -80,6 +72,29 @@ public List<HaxeFieldModel> getFields() {
return fields;
}

private @NotNull List<HaxeFieldModel> getInheritedFields() {
return getCompositeTypes().stream()
.map(ResultHolder::getClassType)
.filter(Objects::nonNull)
.map(HaxeAnonymousTypeModel::mapToHaxeClassIfPossible)
.filter(Objects::nonNull)
.map(haxeClass -> haxeClass.getModel().getFields())
.flatMap(Collection::stream)
.toList();
}

private static @Nullable HaxeClass mapToHaxeClassIfPossible(SpecificHaxeClassReference reference) {
HaxeClass haxeClass = reference.getHaxeClass();
if (reference.isTypeDefOfClass()) {
SpecificTypeReference resolvedRef = reference.fullyResolveTypeDefReference();
if (resolvedRef instanceof SpecificHaxeClassReference classReference) {
return classReference.getHaxeClass();
}
return null;
}
return haxeClass;
}

@Override
public List<HaxeMethodModel> getAllMethods(@Nullable HaxeGenericResolver resolver) {
return getMethods(resolver);
Expand All @@ -103,12 +118,18 @@ private List<HaxeMethodModel> getInheritedMethods(@Nullable HaxeGenericResolver
return getCompositeTypes().stream()
.map(ResultHolder::getClassType)
.filter(Objects::nonNull)
.filter(SpecificHaxeClassReference::isTypeDefOfClass)
.map(classReference -> classReference.resolveTypeDefClass().getHaxeClassModel().getMethods(resolver))
.map(HaxeAnonymousTypeModel::mapToHaxeClassIfPossible)
.filter(Objects::nonNull)
.map(haxeClass -> haxeClass.getModel().getMethods(resolver))
.flatMap(Collection::stream)
.toList();
}

@Override
public @Nullable HaxeMemberModel getMember(String name, @Nullable HaxeGenericResolver resolver) {
return getAllMembers(resolver).stream().filter(model -> model.getName().equals(name)).findFirst().orElse(null);
}

public List<HaxeMemberModel> getAllMembers(@Nullable HaxeGenericResolver resolver) {
return getMembers(resolver);
}
Expand All @@ -131,6 +152,14 @@ private List<HaxeFieldModel> getFieldsFromBody(HaxeAnonymousTypeBody body) {
HaxeFieldModel model = (HaxeFieldModel)field.getModel();
list.add(model);
}

List<HaxeAnonymousTypeFieldList> anonymList = PsiTreeUtil.getChildrenOfAnyType(body, HaxeAnonymousTypeFieldList.class);
for (HaxeAnonymousTypeFieldList fieldList : anonymList) {
for (HaxeAnonymousTypeField field : fieldList.getAnonymousTypeFieldList()) {
HaxeFieldModel model = (HaxeFieldModel)field.getModel();
list.add(model);
}
}
return list;
} else {
return Collections.emptyList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ public List<HaxeGenericParamModel> getGenericParams() {
if (genericParam != null) {
int index = 0;
for (HaxeGenericListPart part : genericParam.getGenericListPartList()) {
// TODO try to avoid recreating this model every time
out.add(new HaxeGenericParamModel(part, index));
index++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,13 @@ private HaxeTypeParameterMultiType convertToMultiTypeParameter(HaxeTypeList list
.toList();

List<HaxeType> typeList = mapped.stream().filter(t -> t.getType() != null).map(HaxeTypeOrAnonymous::getType).toList();

HaxeTypeParameterMultiType type = new HaxeTypeParameterMultiType(part.getNode(), typeList, anonymousTypeBodies);
return type;
if (!typeList.isEmpty() && !anonymousTypes.isEmpty()) {
return HaxeTypeParameterMultiType.withTypeAndAnonymousList(part.getNode(), typeList, anonymousTypeBodies);
} else if (anonymousTypes.isEmpty()) {
return HaxeTypeParameterMultiType.withTypeList(part.getNode(), typeList);
} else {
return HaxeTypeParameterMultiType.withAnonymousList(part.getNode(), anonymousTypeBodies);
}
}

public String toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.intellij.plugins.haxe.lang.psi.HaxeType;
import com.intellij.plugins.haxe.lang.psi.impl.HaxeTypeParameterMultiType;
import com.intellij.plugins.haxe.model.type.HaxeGenericResolver;
import com.intellij.plugins.haxe.model.type.HaxeTypeResolver;
import com.intellij.plugins.haxe.model.type.ResultHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

Expand All @@ -23,4 +25,6 @@ public List<ResultHolder> getCompositeTypes() {
}




}
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ static private ResultHolder _handle(final PsiElement element,
}

if (element instanceof HaxeIfStatement ifStatement) {
return handleIfStatement(context, resolver, ifStatement);
//return handleIfStatement(context, resolver, ifStatement);
return resolveWithCache(ifStatement, resolver, () -> handleIfStatement(context, resolver, ifStatement));
}
}

Expand All @@ -183,7 +184,8 @@ static private ResultHolder _handle(final PsiElement element,
}

if (element instanceof HaxeLocalVarDeclaration varDeclaration) {
return handleLocalVarDeclaration(context, resolver, varDeclaration);
//return handleLocalVarDeclaration(context, resolver, varDeclaration);
return resolveWithCache(varDeclaration, resolver, () -> handleLocalVarDeclaration(context, resolver, varDeclaration));
}

if (element instanceof HaxeLocalFunctionDeclaration functionDeclaration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public class SpecificHaxeClassReference extends SpecificTypeReference {

@Nullable private HaxeClass clazz;

// cache evaluations
Boolean _isTypeDefOfFunction = null;
Boolean _isTypeDefOfClass = null;

// workaround to avoid overflow when wrapping and unwrapping
public boolean isWrapper = false;

Expand Down Expand Up @@ -551,11 +555,17 @@ public boolean isTypeDef() {
}
//TODO MLO: Warning, typedef of typedef will be considered class, should probably return false in this case and create istypeDefOfTypeDef or something
public boolean isTypeDefOfClass() {
return isTypeDef() && ((AbstractHaxeTypeDefImpl)getHaxeClassModel().haxeClass).getTargetClass() != null;
if (_isTypeDefOfClass == null) {
_isTypeDefOfClass = isTypeDef() && ((AbstractHaxeTypeDefImpl)getHaxeClassModel().haxeClass).getTargetClass() != null;
}
return _isTypeDefOfClass;
}

public boolean isTypeDefOfFunction() {
return isTypeDef() && ((AbstractHaxeTypeDefImpl)getHaxeClassModel().haxeClass).getFunctionType() != null;
if (_isTypeDefOfFunction == null) {
_isTypeDefOfFunction = isTypeDef() && ((AbstractHaxeTypeDefImpl)getHaxeClassModel().haxeClass).getFunctionType() != null;
}
return _isTypeDefOfFunction;
}

public SpecificHaxeClassReference resolveTypeDefClass() {
Expand Down Expand Up @@ -595,7 +605,6 @@ public SpecificTypeReference fullyResolveTypeDefReference() {
}
public SpecificTypeReference fullyResolveTypeDefAndUnwrapNullTypeReference() {
if (isTypeParameter()) return this;
HaxeClassModel model = this.getHaxeClassModel();
if (isNullType()) {
SpecificTypeReference typeReference = unwrapNullType();
if (typeReference instanceof SpecificHaxeClassReference reference) {
Expand Down Expand Up @@ -686,8 +695,7 @@ else if (context instanceof HaxeReferenceExpression) {
HaxeReferenceExpression element = (HaxeReferenceExpression)context;
PsiElement resolve = element.resolve();

if (resolve instanceof HaxeClass) {
HaxeClass resolved = (HaxeClass)resolve;
if (resolve instanceof HaxeClass resolved) {
if (element.getText().equals(resolved.getName())) {
return resolved.getName();
}
Expand Down

0 comments on commit b752e9b

Please sign in to comment.