From e8596a7c2f8005167aeebd5d56914832c7533db3 Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Mon, 30 Oct 2023 22:21:02 +0100 Subject: [PATCH] try to reuse FieldModels instead of creating new ones. --- .../semantics/HaxeCallExpressionUtil.java | 13 ++-- .../semantics/HaxeClassAnnotator.java | 2 +- .../semantics/HaxeFieldAnnotator.java | 2 +- .../ide/generation/CreateGetterSetterFix.java | 4 +- .../types/HaxeInlayFieldHintsProvider.java | 2 +- .../haxe/lang/psi/HaxeResolveResult.java | 6 +- .../plugins/haxe/lang/psi/HaxeResolver.java | 2 +- .../haxe/lang/psi/impl/HaxePsiFieldImpl.java | 22 +++---- .../haxe/lang/util/HaxeExpressionUtil.java | 2 +- .../haxe/model/HaxeAnonymousTypeModel.java | 2 +- .../haxe/model/HaxeBaseMemberModel.java | 22 +++---- .../plugins/haxe/model/HaxeClassModel.java | 11 ++-- .../haxe/model/HaxeEnumValueModel.java | 2 +- .../plugins/haxe/model/HaxeFileModel.java | 45 +++++++++----- .../plugins/haxe/model/HaxeMemberModel.java | 25 ++++---- .../haxe/model/HaxeParameterModel.java | 4 +- .../model/type/HaxeExpressionEvaluator.java | 59 ++++++++++--------- .../haxe/model/type/HaxeParameterUtil.java | 3 +- .../haxe/model/type/HaxeTypeResolver.java | 5 +- 19 files changed, 123 insertions(+), 110 deletions(-) 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 bd0efe470..f3fda41e3 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 @@ -736,6 +736,13 @@ else if (resolvedExpression instanceof HaxeMethodDeclaration methodDeclaration) return HaxeTypeResolver.getEnumReturnType(valueDeclaration, referenceExpression.resolveHaxeClass().getGenericResolver()); } } + + // if expression is enumValue we need to resolve the underlying enumType type to test assignment + if (expressionType != null && expressionType.getType() instanceof SpecificEnumValueReference type) { + SpecificHaxeClassReference enumType = type.getEnumClass(); + expressionType = enumType.createHolder(); + } + // anything else is resolved here (literals etc.) if (expressionType == null) { HaxeExpressionEvaluatorContext context = new HaxeExpressionEvaluatorContext(argument); @@ -743,11 +750,7 @@ else if (resolvedExpression instanceof HaxeMethodDeclaration methodDeclaration) expressionType = HaxeExpressionEvaluator.evaluate(argument, context, genericResolver.withoutUnknowns()).result; } - // if expression is enumValue we need to resolve the underlying enumType type to test assignment - if (expressionType != null && expressionType.getType() instanceof SpecificEnumValueReference type) { - SpecificHaxeClassReference enumType = type.getEnumClass(); - expressionType = enumType.createHolder(); - } + return expressionType; } diff --git a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeClassAnnotator.java b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeClassAnnotator.java index 59d52fd30..b4d26e2db 100644 --- a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeClassAnnotator.java +++ b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeClassAnnotator.java @@ -432,7 +432,7 @@ else if (fieldResultClassOnly.isPresent()){ .create(); } - HaxeFieldModel model = new HaxeFieldModel(fieldDeclaration); + HaxeFieldModel model = (HaxeFieldModel) fieldDeclaration.getModel(); HaxeGenericResolver classFieldResolver = HaxeGenericResolverUtil.generateResolverFromScopeParents(model.getBasePsi()); HaxeGenericResolver interfaceFieldResolver = HaxeGenericResolverUtil.generateResolverFromScopeParents(intField.getBasePsi()); diff --git a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeFieldAnnotator.java b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeFieldAnnotator.java index 7721b5617..9392f74e1 100644 --- a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeFieldAnnotator.java +++ b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeFieldAnnotator.java @@ -28,7 +28,7 @@ public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder hold } public static void check(final HaxeFieldDeclaration var, final AnnotationHolder holder) { - HaxeFieldModel field = new HaxeFieldModel(var); + HaxeFieldModel field = (HaxeFieldModel)var.getModel(); if (field.isProperty()) { checkProperty(field, holder); } diff --git a/src/main/java/com/intellij/plugins/haxe/ide/generation/CreateGetterSetterFix.java b/src/main/java/com/intellij/plugins/haxe/ide/generation/CreateGetterSetterFix.java index 88d58c043..5d311744c 100644 --- a/src/main/java/com/intellij/plugins/haxe/ide/generation/CreateGetterSetterFix.java +++ b/src/main/java/com/intellij/plugins/haxe/ide/generation/CreateGetterSetterFix.java @@ -66,11 +66,11 @@ public CreateGetterSetterFix(final HaxeClass haxeClass, Strategy strategy) { @Override protected String buildFunctionsText(HaxeNamedComponent namedComponent) { - if (!(namedComponent instanceof HaxeFieldDeclaration)) { + if (!(namedComponent instanceof HaxeFieldDeclaration fieldDeclaration)) { return ""; } - HaxeFieldModel field = new HaxeFieldModel((HaxeFieldDeclaration)namedComponent); + HaxeFieldModel field = (HaxeFieldModel)fieldDeclaration.getModel(); final StringBuilder result = new StringBuilder(); if (myStratagy == Strategy.GETTER || myStratagy == Strategy.GETTERSETTER) { HaxeNamedComponent getterMethod = myHaxeClass.findHaxeMethodByName(HaxePresentableUtil.getterName(field.getName()), null); diff --git a/src/main/java/com/intellij/plugins/haxe/ide/hint/types/HaxeInlayFieldHintsProvider.java b/src/main/java/com/intellij/plugins/haxe/ide/hint/types/HaxeInlayFieldHintsProvider.java index 8f37d830e..745be6fa8 100644 --- a/src/main/java/com/intellij/plugins/haxe/ide/hint/types/HaxeInlayFieldHintsProvider.java +++ b/src/main/java/com/intellij/plugins/haxe/ide/hint/types/HaxeInlayFieldHintsProvider.java @@ -37,7 +37,7 @@ public void collectFromElement(@NotNull PsiElement element, @NotNull InlayTreeSi private static void handleFieldDeclarationHints(@NotNull PsiElement element, @NotNull InlayTreeSink sink, HaxeFieldDeclaration fieldDeclaration) { - HaxeFieldModel field = new HaxeFieldModel(fieldDeclaration); + HaxeFieldModel field = (HaxeFieldModel)fieldDeclaration.getModel(); if (!field.hasTypeTag()) { diff --git a/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolveResult.java b/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolveResult.java index 4e734f0df..9fefadbe9 100644 --- a/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolveResult.java +++ b/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolveResult.java @@ -162,12 +162,12 @@ public static HaxeResolveResult create(@Nullable HaxeClass aClass, HaxeGenericSp // could be due to cache for Psi resolve while it looks like resolve by QName does not and searches file tree. HaxeClass superclass = null; PsiElement resolve = haxeType.getReferenceExpression().resolve(); - if (resolve instanceof HaxeClassDeclaration classDeclaration) { - superclass = classDeclaration.getModel().haxeClass; + if (resolve instanceof HaxeClass haxeClass) { + superclass = haxeClass.getModel().haxeClass; } if (superclass == null) { - // if reference resolve fails do QName resolve as fallback + // if reference resolve fails, do QName resolve as fallback superclass = HaxeResolveUtil.tryResolveClassByQName(haxeType); } // hopefully it won't be necessary to traverse the entire type hierarchy and we only need to check classes and interfaces that are generic 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 f49b0849e..ddb6e5283 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 @@ -601,7 +601,7 @@ private List checkIsAccessor(HaxeReference reference) { final HaxeFieldDeclaration varDeclaration = PsiTreeUtil.getParentOfType(reference, HaxeFieldDeclaration.class); if (varDeclaration == null) return null; - final HaxeFieldModel fieldModel = new HaxeFieldModel(varDeclaration); + final HaxeFieldModel fieldModel = (HaxeFieldModel)varDeclaration.getModel(); final HaxeMethodModel method = accessorType == HaxeAccessorType.GET ? fieldModel.getGetterMethod() : fieldModel.getSetterMethod(); if (method != null) { diff --git a/src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxePsiFieldImpl.java b/src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxePsiFieldImpl.java index 4c9347d52..c857bdcb3 100644 --- a/src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxePsiFieldImpl.java +++ b/src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxePsiFieldImpl.java @@ -22,9 +22,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.LogLevel; import com.intellij.plugins.haxe.lang.psi.*; -import com.intellij.plugins.haxe.model.HaxeEnumValueModel; -import com.intellij.plugins.haxe.model.HaxeFieldModel; -import com.intellij.plugins.haxe.model.HaxeModel; +import com.intellij.plugins.haxe.model.*; import com.intellij.plugins.haxe.util.HaxeAbstractEnumUtil; import com.intellij.plugins.haxe.util.UsefulPsiTreeUtil; @@ -56,15 +54,19 @@ public HaxePsiFieldImpl(ASTNode node) { super(node); } + private HaxeMemberModel _model = null; @Override - public HaxeModel getModel() { - if (this instanceof HaxeEnumValueDeclaration) { - return new HaxeEnumValueModel((HaxeEnumValueDeclaration)this); - } - if (HaxeAbstractEnumUtil.isAbstractEnum(getContainingClass()) && HaxeAbstractEnumUtil.couldBeAbstractEnumField(this)) { - return new HaxeEnumValueModel((HaxeFieldDeclaration)this); + public HaxeMemberModel getModel() { + if (_model == null) { + if (this instanceof HaxeEnumValueDeclaration enumValueDeclaration) { + _model = new HaxeEnumValueModel(enumValueDeclaration); + }else if (HaxeAbstractEnumUtil.isAbstractEnum(getContainingClass()) && HaxeAbstractEnumUtil.couldBeAbstractEnumField(this)) { + _model = new HaxeEnumValueModel((HaxeFieldDeclaration)this); + }else{ + _model = new HaxeFieldModel(this); + } } - return new HaxeFieldModel(this); + return _model; } @Override diff --git a/src/main/java/com/intellij/plugins/haxe/lang/util/HaxeExpressionUtil.java b/src/main/java/com/intellij/plugins/haxe/lang/util/HaxeExpressionUtil.java index 6366912f4..f3ff1a17c 100644 --- a/src/main/java/com/intellij/plugins/haxe/lang/util/HaxeExpressionUtil.java +++ b/src/main/java/com/intellij/plugins/haxe/lang/util/HaxeExpressionUtil.java @@ -260,7 +260,7 @@ private static ConstantClass innerClassifier(HaxeExpression expr) { } if (resolved instanceof HaxeFieldDeclaration) { HaxeFieldDeclaration fieldDeclaration = (HaxeFieldDeclaration)resolved; - HaxeFieldModel fieldModel = new HaxeFieldModel(fieldDeclaration); + HaxeFieldModel fieldModel = (HaxeFieldModel)fieldDeclaration.getModel(); return classifyConstantExpression(fieldModel.getInitializerExpression()); } return resolved instanceof HaxeExpression diff --git a/src/main/java/com/intellij/plugins/haxe/model/HaxeAnonymousTypeModel.java b/src/main/java/com/intellij/plugins/haxe/model/HaxeAnonymousTypeModel.java index 15bc79d39..9f4ff83a1 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeAnonymousTypeModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeAnonymousTypeModel.java @@ -95,7 +95,7 @@ private List getFieldsFromBody(HaxeAnonymousTypeBody body) { List list = new ArrayList<>(); List children = PsiTreeUtil.getChildrenOfAnyType(body, HaxeFieldDeclaration.class, HaxeAnonymousTypeField.class, HaxeEnumValueDeclaration.class); for (HaxePsiField field : children) { - HaxeFieldModel model = new HaxeFieldModel(field); + HaxeFieldModel model = (HaxeFieldModel)field.getModel(); list.add(model); } return list; diff --git a/src/main/java/com/intellij/plugins/haxe/model/HaxeBaseMemberModel.java b/src/main/java/com/intellij/plugins/haxe/model/HaxeBaseMemberModel.java index 68fdf2123..300199e1c 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeBaseMemberModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeBaseMemberModel.java @@ -33,7 +33,6 @@ import org.jetbrains.annotations.Nullable; public abstract class HaxeBaseMemberModel implements HaxeModel { - protected static final Key DECLARING_CLASS_MODEL_KEY = new Key<>("HAXE_DECLARING_CLASS_MODEL"); protected PsiElement basePsi; protected HaxeDocumentModel document = null; @@ -43,23 +42,18 @@ public HaxeBaseMemberModel(PsiElement basePsi) { static private HaxeNamedComponent getNamedComponentPsi(PsiElement element) { if (element == null) return null; - if (element instanceof HaxeNamedComponent) return (HaxeNamedComponent)element; - if (element.getParent() instanceof HaxeNamedComponent) return (HaxeNamedComponent)element.getParent(); + if (element instanceof HaxeNamedComponent namedComponent) return namedComponent; + if (element.getParent() instanceof HaxeNamedComponent parentNamedComponent) return parentNamedComponent; return getNamedComponentPsi(UsefulPsiTreeUtil.getChild(element, HaxeNamedComponent.class)); } public static HaxeBaseMemberModel fromPsi(PsiElement element) { - if (element instanceof HaxeMethod) return ((HaxeMethod)element).getModel(); - if (element instanceof HaxeFieldDeclaration) { - PsiClass containingClass = ((HaxeFieldDeclaration)element).getContainingClass(); - if (HaxeAbstractEnumUtil.isAbstractEnum(containingClass) && HaxeAbstractEnumUtil.couldBeAbstractEnumField(element)) { - return new HaxeEnumValueModel((HaxeFieldDeclaration)element); - } - return new HaxeFieldModel((HaxeFieldDeclaration)element); - } - if (element instanceof HaxeEnumValueDeclaration) return new HaxeEnumValueModel((HaxeEnumValueDeclaration)element); - if (element instanceof HaxeLocalVarDeclaration) return new HaxeLocalVarModel((HaxeLocalVarDeclaration)element); - if (element instanceof HaxeAnonymousTypeField) return new HaxeAnonymousTypeFieldModel((HaxeAnonymousTypeField)element); + if (element instanceof HaxeMethod method) return method.getModel(); + if (element instanceof HaxeFieldDeclaration fieldDeclaration) return (HaxeBaseMemberModel)fieldDeclaration.getModel(); + if (element instanceof HaxeEnumValueDeclaration enumValueDeclaration) return (HaxeBaseMemberModel) enumValueDeclaration.getModel(); + if (element instanceof HaxeLocalVarDeclaration varDeclaration) return (HaxeBaseMemberModel) varDeclaration.getModel(); + if (element instanceof HaxeAnonymousTypeField anonymousTypeField) return (HaxeBaseMemberModel) anonymousTypeField.getModel(); + if (element instanceof HaxeParameter) return new HaxeParameterModel((HaxeParameter)element); if (element instanceof HaxeForStatement) return null; final PsiElement parent = element.getParent(); 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 bc0511976..c595e5610 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeClassModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeClassModel.java @@ -513,7 +513,7 @@ public List getMembersSelf() { public HaxeFieldModel getField(String name, @Nullable HaxeGenericResolver resolver) { HaxePsiField field = (HaxePsiField)haxeClass.findHaxeFieldByName(name, resolver); if (field instanceof HaxeFieldDeclaration || field instanceof HaxeAnonymousTypeField || field instanceof HaxeEnumValueDeclaration) { - return new HaxeFieldModel(field); + return (HaxeFieldModel)field.getModel(); } return null; } @@ -625,7 +625,7 @@ public List getFields() { List list = new ArrayList<>(); List children = PsiTreeUtil.getChildrenOfAnyType(body, HaxeFieldDeclaration.class, HaxeAnonymousTypeField.class, HaxeEnumValueDeclaration.class); for (HaxePsiField field : children) { - HaxeFieldModel model = new HaxeFieldModel(field); + HaxeFieldModel model = (HaxeFieldModel)field.getModel(); list.add(model); } return list; @@ -835,10 +835,9 @@ public List getExposedMembers() { if (body != null) { for (HaxeNamedComponent declaration : PsiTreeUtil.getChildrenOfAnyType(body, HaxeFieldDeclaration.class, HaxeMethod.class)) { if (!(declaration instanceof PsiMember)) continue; - if (declaration instanceof HaxeFieldDeclaration) { - HaxeFieldDeclaration varDeclaration = (HaxeFieldDeclaration)declaration; + if (declaration instanceof HaxeFieldDeclaration varDeclaration) { if (varDeclaration.isPublic() && varDeclaration.isStatic()) { - out.add(new HaxeFieldModel((HaxeFieldDeclaration)declaration)); + out.add(varDeclaration.getModel()); } } else { HaxeMethodDeclaration method = (HaxeMethodDeclaration)declaration; @@ -853,7 +852,7 @@ public List getExposedMembers() { if (body != null) { List declarations = body.getEnumValueDeclarationList(); for (HaxeEnumValueDeclaration declaration : declarations) { - out.add(new HaxeFieldModel(declaration)); + out.add(declaration.getModel()); } } } diff --git a/src/main/java/com/intellij/plugins/haxe/model/HaxeEnumValueModel.java b/src/main/java/com/intellij/plugins/haxe/model/HaxeEnumValueModel.java index 199369626..d0c9e8696 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeEnumValueModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeEnumValueModel.java @@ -25,7 +25,7 @@ import static com.intellij.plugins.haxe.util.HaxePresentableUtil.getPresentableParameterList; -public class HaxeEnumValueModel extends HaxeMemberModel { +public class HaxeEnumValueModel extends HaxeFieldModel { private final boolean isAbstractType; private final boolean hasConstructor; private final boolean hasReturnType; diff --git a/src/main/java/com/intellij/plugins/haxe/model/HaxeFileModel.java b/src/main/java/com/intellij/plugins/haxe/model/HaxeFileModel.java index 64c3dea63..05748066e 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeFileModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeFileModel.java @@ -16,7 +16,6 @@ */ package com.intellij.plugins.haxe.model; -import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; import com.intellij.plugins.haxe.lang.psi.*; import com.intellij.plugins.haxe.util.HaxeAddImportHelper; @@ -95,10 +94,10 @@ public HaxeClassModel getMainClassModel() { @Nullable public HaxeClassModel getClassModel(String name) { - Optional module = getModuleBody(); + HaxeModule module = getModuleBody(); - if (module.isPresent()) { - HaxeClass haxeClass = (HaxeClass)Arrays.stream(module.get().getChildren()) + if (module != null) { + HaxeClass haxeClass = (HaxeClass)Arrays.stream(module.getChildren()) .filter(element -> { if (element instanceof HaxeClass hxClass) { PsiIdentifier identifier = hxClass.getNameIdentifier(); @@ -115,16 +114,30 @@ public HaxeClassModel getClassModel(String name) { return null; } - @NotNull - public Optional getModuleBody() { - return Arrays.stream(file.getChildren()) - .filter(element -> (element instanceof HaxeModule)) - .map(element -> (HaxeModule)element) - .findFirst(); + @Nullable + public HaxeModule getModuleBody() { + for (PsiElement element : getChildren()) { + if ((element instanceof HaxeModule module)) { + return module; + } + } + return null; + } + @Nullable + private PsiElement[] getChildren() { + return CachedValuesManager.getProjectPsiDependentCache(file, HaxeFileModel::_getChildren).getValue(); + } + + private static CachedValueProvider.Result _getChildren(HaxeFile file) { + PsiElement[] children = file.getChildren(); + return new CachedValueProvider.Result<>(children, children); } + @NotNull public PsiElement[] getModuleBodyChildren() { - return getModuleBody().map(PsiElement::getChildren).orElseGet(() ->PsiElement.EMPTY_ARRAY); + HaxeModule body = getModuleBody(); + if (body == null) return PsiElement.EMPTY_ARRAY; + return body.getChildren(); } @NotNull @@ -185,35 +198,35 @@ public Stream getClassModelsStream() { } public List getImportStatements() { - return Arrays.stream(file.getChildren()) + return Arrays.stream(getChildren()) .filter(element -> element instanceof HaxeImportStatement) .map(element -> ((HaxeImportStatement)element)) .collect(Collectors.toList()); } public List getImportModels() { - return Arrays.stream(file.getChildren()) + return Arrays.stream(getChildren()) .filter(element -> element instanceof HaxeImportStatement) .map(element -> ((HaxeImportStatement)element).getModel()) .collect(Collectors.toList()); } public List getUsingStatements() { - return Arrays.stream(file.getChildren()) + return Arrays.stream(getChildren()) .filter(element -> element instanceof HaxeUsingStatement) .map(element -> (HaxeUsingStatement)element) .collect(Collectors.toList()); } public List getUsingModels() { - return Arrays.stream(file.getChildren()) + return Arrays.stream(getChildren()) .filter(element -> element instanceof HaxeUsingStatement) .map(element -> ((HaxeUsingStatement)element).getModel()) .collect(Collectors.toList()); } @NotNull public List getOrderedImportAndUsingModels() { - PsiElement[] children = file.getChildren(); + PsiElement[] children = getChildren(); List result = new ArrayList<>(); for(PsiElement child : children) { diff --git a/src/main/java/com/intellij/plugins/haxe/model/HaxeMemberModel.java b/src/main/java/com/intellij/plugins/haxe/model/HaxeMemberModel.java index a44da1107..2c0ba6263 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeMemberModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeMemberModel.java @@ -19,9 +19,7 @@ */ package com.intellij.plugins.haxe.model; -import com.intellij.plugins.haxe.lang.psi.HaxeBinaryExpression; -import com.intellij.plugins.haxe.lang.psi.HaxeClass; -import com.intellij.plugins.haxe.lang.psi.HaxePsiModifier; +import com.intellij.plugins.haxe.lang.psi.*; import com.intellij.plugins.haxe.metadata.HaxeMetadataList; import com.intellij.plugins.haxe.metadata.psi.HaxeMeta; import com.intellij.plugins.haxe.metadata.psi.HaxeMetadataCompileTimeMeta; @@ -29,6 +27,8 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMember; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; @@ -98,17 +98,18 @@ private boolean isOverriddenPublicMethod() { @Override public HaxeClassModel getDeclaringClass() { - HaxeClassModel model = getBasePsi().getUserData(DECLARING_CLASS_MODEL_KEY); - if (model == null) { - PsiClass containingClass = getMemberPsi().getContainingClass(); - if (containingClass instanceof HaxeClass) { - model = ((HaxeClass)containingClass).getModel(); - getBasePsi().putUserData(DECLARING_CLASS_MODEL_KEY, model); - } - } + return CachedValuesManager.getProjectPsiDependentCache(getMemberPsi(), HaxeMemberModel::_getDeclaringClass).getValue(); + } - return model; + private static CachedValueProvider.Result _getDeclaringClass(PsiMember member) { + PsiClass containingClass = member.getContainingClass(); + if (containingClass instanceof HaxeClass haxeClass) { + return new CachedValueProvider.Result<>(haxeClass.getModel(), member); + }else { + return new CachedValueProvider.Result<>(null, member); + } } + public boolean isInInterface() { return getDeclaringClass().isInterface(); } diff --git a/src/main/java/com/intellij/plugins/haxe/model/HaxeParameterModel.java b/src/main/java/com/intellij/plugins/haxe/model/HaxeParameterModel.java index 43750e312..8fa4efa55 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeParameterModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeParameterModel.java @@ -136,8 +136,8 @@ public HaxeMemberModel getMemberModel() { final PsiMember parentPsi = PsiTreeUtil.getParentOfType(getBasePsi(), HaxeEnumValueDeclaration.class, HaxeMethod.class); if (parentPsi instanceof HaxeMethod) { model = ((HaxeMethod)parentPsi).getModel(); - } else if (parentPsi instanceof HaxeEnumValueDeclaration) { - model = new HaxeFieldModel((HaxePsiField)parentPsi); + } else if (parentPsi instanceof HaxeEnumValueDeclaration haxeEnumValueDeclaration) { + model = (HaxeFieldModel) haxeEnumValueDeclaration.getModel(); } if (model != null) { getBasePsi().putUserData(PARAMETER_MEMBER_MODEL_KEY, model); 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 454d437e4..ded1a2ae8 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 @@ -431,7 +431,6 @@ else if (expression instanceof HaxeArrayLiteral arrayLiteral) { } if (element instanceof HaxeCastExpression castExpression) { - handle(((HaxeCastExpression)element).getExpression(), context, resolver); HaxeTypeOrAnonymous anonymous = castExpression.getTypeOrAnonymous(); if (anonymous != null) { return HaxeTypeResolver.getTypeFromTypeOrAnonymous(anonymous); @@ -1318,37 +1317,39 @@ else if (getter instanceof HaxeExternInterfaceDeclaration interfaceDeclaration) if (element instanceof HaxeIsTypeExpression) { return SpecificHaxeClassReference.primitive("Bool", element, null).createHolder(); } - //TODO check if common parent of the next if - if ( - (element instanceof HaxeAdditiveExpression) || - (element instanceof HaxeModuloExpression) || - (element instanceof HaxeBitwiseExpression) || - (element instanceof HaxeShiftExpression) || - (element instanceof HaxeLogicAndExpression) || - (element instanceof HaxeLogicOrExpression) || - (element instanceof HaxeCompareExpression) || - (element instanceof HaxeCoalescingExpression) || - (element instanceof HaxeMultiplicativeExpression) + //check if common parent before checking all accepted variants (note should not include HaxeAssignExpression, HaxeIteratorExpression etc) + if (element instanceof HaxeBinaryExpression) { + if ( + (element instanceof HaxeAdditiveExpression) || + (element instanceof HaxeModuloExpression) || + (element instanceof HaxeBitwiseExpression) || + (element instanceof HaxeShiftExpression) || + (element instanceof HaxeLogicAndExpression) || + (element instanceof HaxeLogicOrExpression) || + (element instanceof HaxeCompareExpression) || + (element instanceof HaxeCoalescingExpression) || + (element instanceof HaxeMultiplicativeExpression) ) { - PsiElement[] children = element.getChildren(); - String operatorText; - if (children.length == 3) { - operatorText = children[1].getText(); - SpecificTypeReference left = handle(children[0], context, resolver).getType(); - SpecificTypeReference right = handle(children[2], context, resolver).getType(); - left = resolveAnyTypeDefs(left); - right = resolveAnyTypeDefs(right); - return HaxeOperatorResolver.getBinaryOperatorResult(element, left, right, operatorText, context).createHolder(); - } else { - operatorText = getOperator(element, HaxeTokenTypeSets.OPERATORS); - SpecificTypeReference left = handle(children[0], context, resolver).getType(); - SpecificTypeReference right = handle(children[1], context, resolver).getType(); - left = resolveAnyTypeDefs(left); - right = resolveAnyTypeDefs(right); - return HaxeOperatorResolver.getBinaryOperatorResult(element, left, right, operatorText, context).createHolder(); + PsiElement[] children = element.getChildren(); + String operatorText; + if (children.length == 3) { + operatorText = children[1].getText(); + SpecificTypeReference left = handle(children[0], context, resolver).getType(); + SpecificTypeReference right = handle(children[2], context, resolver).getType(); + left = resolveAnyTypeDefs(left); + right = resolveAnyTypeDefs(right); + return HaxeOperatorResolver.getBinaryOperatorResult(element, left, right, operatorText, context).createHolder(); + } + else { + operatorText = getOperator(element, HaxeTokenTypeSets.OPERATORS); + SpecificTypeReference left = handle(children[0], context, resolver).getType(); + SpecificTypeReference right = handle(children[1], context, resolver).getType(); + left = resolveAnyTypeDefs(left); + right = resolveAnyTypeDefs(right); + return HaxeOperatorResolver.getBinaryOperatorResult(element, left, right, operatorText, context).createHolder(); + } } } - if (element instanceof HaxeTypeCheckExpr typeCheckExpr) { PsiElement[] children = element.getChildren(); if (children.length == 2) { diff --git a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeParameterUtil.java b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeParameterUtil.java index 127fd121a..f6db175f5 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/type/HaxeParameterUtil.java +++ b/src/main/java/com/intellij/plugins/haxe/model/type/HaxeParameterUtil.java @@ -38,7 +38,8 @@ public static Map mapArgumentsToParamet for (; counter < parameterCount; counter++) { HaxeParameterModel parameter = parameterModelList.get(counter); parameterTypeHolder = parameter.getType(); - parameterTypeHolder = resolveAnyGenericType(parameterTypeHolder); + //TODO rewrite getType to get Type Without resolving typeParameters, and then do it before any useage, that way we can cache the value + //parameterTypeHolder = resolveAnyGenericType(parameterTypeHolder); if (argumentCount < counter) { map.put(counter, new ParameterToArgumentAndResolver(counter, parameter, null,null,null)); 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 655a2385d..9dd035054 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 @@ -561,10 +561,9 @@ static public ResultHolder getPsiElementType(@NotNull PsiElement element, @Nulla if (null != resultHolder) { // If it's a constant, grab the constant value. if (targetElement instanceof HaxePsiField field) { - HaxeFieldModel model = new HaxeFieldModel(field); + HaxeFieldModel model = (HaxeFieldModel)field.getModel(); if (model.isConstant()) { - resultHolder = resultHolder.withConstantValue( - model.isEnumValue() ? model.getBasePsi() : model.getInitializerExpression()); + resultHolder = resultHolder.withConstantValue(model.isEnumValue() ? model.getBasePsi() : model.getInitializerExpression()); } } if (targetElement instanceof HaxeLocalVarDeclaration varDeclaration) {