Skip to content

Commit

Permalink
Fixing Enum import and inference issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
m0rkeulv committed Apr 16, 2024
1 parent 8df6227 commit 7170f0d
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 9 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
## 1.5.2
* Fixed: Methods and properties in module scope are now resolved correctly.
* Fixed: Issue with reification parsing
* Fixed: incorrect type parameter use in some cases where Method typeParameter and classParameter was the same name.
* Fixed: Issue parsing switchCaseExtractors in objectLiterals
* Fixed: Issue with Enum unification
* Fixed: Issue where try-catch valueExpressions was not correctly evaluated
* Fixed: Typedefs are now fully resolved to find Enum values from modules imported using `using` statements
* Fixed: Incorrect type parameter use in some cases where Method typeParameter and classParameter was the same name.

## 1.5.1
* Fixed: Issue setting up Haxe SDK in intelliJ 2024.1
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/intellij/plugins/haxe/lang/parser/haxe.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ objectLiteral ::= nonEmptyObjectLiteral | emptyObjectLiteral

private objectLiteralElementList ::= objectLiteralElement (',' objectLiteralElement)* ','? {pin=1 recoverWhile="object_literal_list_recover"}
private object_literal_list_recover ::= !('}')

objectLiteralElement ::= (identifier | stringLiteralExpression) ':' expression {pin=2 recoverWhile="object_literal_part_recover"}
// extractor match expression can contain ObjectLiterals and we need to allow extractors inside these expressions
private expressionOrExtractorMatchExpression ::= switchCaseExtractor | expression {extends=expression}
objectLiteralElement ::= (identifier | stringLiteralExpression) ':' expressionOrExtractorMatchExpression {pin=2 recoverWhile="object_literal_part_recover"}
private object_literal_part_recover ::= !(',' | '}')
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,14 @@ private List<? extends PsiElement> doResolveInner(@NotNull HaxeReference referen

// checks if we are attempting to assign an enum type, this makes sure we chose the enum value and not competing class names
private List<? extends PsiElement> checkEnumMemberHints(HaxeReference reference) {
if (reference.getParent() instanceof HaxeEnumValueReference) {
HaxeSwitchCaseExpr switchCaseExpr = PsiTreeUtil.getParentOfType(reference, HaxeSwitchCaseExpr.class, true);
if (switchCaseExpr != null) {
HaxeExtractorMatchExpression matchExpression = PsiTreeUtil.getParentOfType(reference, HaxeExtractorMatchExpression.class);
if (matchExpression != null) {
List<HaxeComponentName> names = evaluateAndFindEnumMember(reference, matchExpression.getExpression());
if (names!= null && !names.isEmpty()) return names;
}
HaxeSwitchStatement parentSwitch = PsiTreeUtil.getParentOfType(reference, HaxeSwitchStatement.class);
if (parentSwitch != null) {
HaxeExpression expression = parentSwitch.getExpression();
Expand All @@ -306,7 +312,7 @@ private List<? extends PsiElement> checkEnumMemberHints(HaxeReference reference)
if (components != null) return components;
}
}

}

PsiElement referenceParent = reference.getParent();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package com.intellij.plugins.haxe.model;

import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.CachedValueProvider;
Expand All @@ -30,6 +32,8 @@
public abstract class HaxeImportableModel implements HaxeExposableModel {
protected final PsiElement basePsi;

private static final RecursionGuard<PsiElement> typeDefRecursionGuard = RecursionManager.createGuard("typeDefRecursionGuard");

protected HaxeImportableModel(@NotNull PsiElement element) {
this.basePsi = element;
}
Expand Down Expand Up @@ -112,6 +116,13 @@ private static HaxeModel getExposedMemberFromTypeDefReference(String name, HaxeM
HaxeType type = typeOrAnonymous.getType();
if (type != null) {
PsiElement resolve = type.getReferenceExpression().resolve();
if (resolve instanceof HaxeTypedefDeclaration declaration) {
HaxeModel haxeModel = typeDefRecursionGuard.doPreventingRecursion(typedefDeclaration, true, () ->
{
return getExposedMemberFromTypeDefReference(name, declaration.getModel(), declaration);
});
if (haxeModel != null) return haxeModel;
}
if (resolve instanceof HaxeEnumDeclaration enumDeclaration) {
if (enumDeclaration.getModel() instanceof HaxeEnumModel enumModel) {
HaxeModel memberFromEnum = getExposedMemberFromEnum(name, model, enumModel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ static private ResultHolder _handle(final PsiElement element,
return handleTryStatement(context, resolver, tryStatement);
}

if (element instanceof HaxeCatchStatement catchStatement) {
return handleCatchStatement(context, resolver, catchStatement);
}

if (element instanceof HaxeForStatement forStatement) {
return handleForStatement(context, resolver, forStatement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
public class HaxeExpressionEvaluatorHandlers {


//private static ThreadLocal<HashSet<PsiElement>> resolvesInProcess = new ThreadLocal<>().withInitial(()->new HashSet<PsiElement>());
private static final RecursionGuard<PsiElement>
evaluatorHandlersRecursionGuard = RecursionManager.createGuard("EvaluatorHandlersRecursionGuard");

Expand Down Expand Up @@ -1627,6 +1626,23 @@ static ResultHolder handleTryStatement(HaxeExpressionEvaluatorContext context,
}
return HaxeTypeUnifier.unifyHolders(blockResults, tryStatement);
}
@NotNull
static ResultHolder handleCatchStatement(HaxeExpressionEvaluatorContext context,
HaxeGenericResolver resolver,
HaxeCatchStatement catchStatement) {
// try-catch can be used as a value expression all blocks must be evaluated and unified
// we should also iterate trough so we can pick up any return statements
@NotNull PsiElement[] children = catchStatement.getChildren();
HaxeParameter parameter = catchStatement.getParameter();
List<ResultHolder> blockResults = new ArrayList<>();
for (PsiElement child : children) {
if (child == parameter) continue;
blockResults.add(handle(child, context, resolver));
}
return HaxeTypeUnifier.unifyHolders(blockResults, catchStatement);
}



static ResultHolder handleReturnStatement(HaxeExpressionEvaluatorContext context,
HaxeGenericResolver resolver,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,31 @@ static public SpecificTypeReference unify(SpecificTypeReference a, SpecificTypeR
if (a.isEnumValue() && b.isEnumValue()) {
return unifyEnumValues(a, b);
}
if (a.isEnumType() && b.isEnumValue()) {
else if (a.isEnumType() && b.isEnumValue()) {
return unifyEnumValues(a, b);
}
SpecificTypeReference commonEnumClass = tryToFindCommonEnumClass(a, b, context);
if (commonEnumClass != null) return commonEnumClass;

return SpecificTypeReference.getUnknown(a.getElementContext());
return SpecificTypeReference.getUnknown(context);
}

private static @Nullable SpecificTypeReference tryToFindCommonEnumClass(SpecificTypeReference a,
SpecificTypeReference b,
@NotNull PsiElement context) {

SpecificTypeReference possibleAChange = a;
SpecificTypeReference possibleBChange = b;
if (a instanceof SpecificEnumValueReference valueReference) {
possibleAChange = valueReference.getEnumClass();
}
if (b instanceof SpecificEnumValueReference valueReference) {
possibleBChange = valueReference.getEnumClass();
}
if (possibleAChange != a || possibleBChange != b) {
return unify(possibleAChange, possibleBChange, context);
}
return null;
}

@NotNull
Expand Down Expand Up @@ -215,8 +235,8 @@ static public SpecificTypeReference unifyEnumValues(SpecificTypeReference a, Spe
if (b.isEnumValueClass()) {
return a;
}
else if (b instanceof SpecificEnumValueReference) {
return ((SpecificEnumValueReference)b).clone();
else if (b instanceof SpecificEnumValueReference enumValueReference) {
return enumValueReference.clone();
}
}
else if (a instanceof SpecificHaxeClassReference && b instanceof SpecificEnumValueReference bReference) {
Expand Down

0 comments on commit 7170f0d

Please sign in to comment.