Skip to content

Commit 9108c05

Browse files
committed
Stack overflow fix and better resolving untyped parameters.
1 parent 4d37da5 commit 9108c05

11 files changed

+212
-115
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
22
## 1.4.42
3-
* Bugfix: function bindings was incorrectly treated as static extensions
3+
* Bugfix: Function bindings was incorrectly treated as static extensions
4+
* Bugfix: Stack overflow when resolving expression type
5+
* Misc resolver tweaks to better resolve untyped parameters and performance
6+
47
## 1.4.41
58
* Bugfix: fixed type resolve regression for iterators
69
## 1.4.40

gradle.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
org.gradle.jvmargs =-Xmx1g
12
# IntelliJ Platform Artifacts Repositories
23
# -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html
34

@@ -6,7 +7,7 @@ pluginName = Haxe Toolkit Support
67
pluginRepositoryUrl = https://github.com/HaxeFoundation/intellij-haxe
78

89
# SemVer format -> https://semver.org
9-
pluginVersion = 1.4.41
10+
pluginVersion = 1.4.42
1011

1112
# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
1213
platformType = IU

src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolver.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ private List<? extends PsiElement> doResolveInner(@NotNull HaxeReference referen
273273
if (result == null) {
274274
LogResolution(reference, "failed after exhausting all options.");
275275
}
276-
if (result == null) {
276+
if (result == null || result.isEmpty()) {
277277
// to avoid caching empty due to already being resolved we mark
278278
// elements so we know if we want to cache as not found or just skip (null is not cached, empty list is cached)
279279
if (incompleteCode || reference.getUserData(skipCacheKey) == Boolean.TRUE) {
@@ -608,7 +608,7 @@ private List<? extends PsiElement> checkIsSwitchVar(HaxeReference reference) {
608608

609609
// NOTE: this one has to come before `checkIfSwitchCaseDefaultValue`
610610
// check if default name in match expression (ex `case TString(_ => captureVar)`)
611-
if (result == null) result = checkIfDefaultValueInMatchExpression(reference, switchCaseExpr);
611+
result = checkIfDefaultValueInMatchExpression(reference, switchCaseExpr);
612612

613613
// check if matches default name ( ex. `case _:`)
614614
if (result == null) result = checkIfSwitchCaseDefaultValue(reference);
@@ -873,7 +873,6 @@ private List<? extends PsiElement> checkIsFullyQualifiedStatement(@NotNull HaxeR
873873
if (parent != null) {
874874

875875
//TODO check for @:using on haxeType and add to using (this might not be the correct place, but its a reminder to add it somewhere in the resolver logic)
876-
// TODO if using, include all members from file for resolving ( qualified path / package + memberName in using should resolve)
877876

878877
LogResolution(reference, "via parent/package import.");
879878
return asList(resolveQualifiedReference(reference));
@@ -916,12 +915,10 @@ private List<? extends PsiElement> resolveChain(HaxeReference lefthandExpression
916915
}
917916

918917
// Check 'using' classes.
919-
HaxeClass leftClass = leftExpression.getHaxeClass();
920-
if (leftClass != null) {
921918
HaxeFileModel fileModel = HaxeFileModel.fromElement(reference.getContainingFile());
922919

923920
// Add the global usings to the top of the list (so they're checked last).
924-
HaxeProjectModel projectModel = HaxeProjectModel.fromElement(leftClass);
921+
HaxeProjectModel projectModel = HaxeProjectModel.fromElement(reference);
925922
HaxeStdPackageModel stdPackageModel = (HaxeStdPackageModel)projectModel.getStdPackage();
926923
final List<HaxeUsingModel> usingModels = new ArrayList<>(stdPackageModel.getGlobalUsings());
927924

@@ -943,7 +940,12 @@ private List<? extends PsiElement> resolveChain(HaxeReference lefthandExpression
943940
if (log.isTraceEnabled()) log.trace("Found method in 'using' import: " + foundMethod.getName());
944941
return asList(foundMethod.getBasePsi());
945942
}
946-
}
943+
// check other types ("using" can be used to find typedefsetc)
944+
PsiElement element = usingModels.get(i).exposeByName(identifier);
945+
if (element != null) {
946+
if (log.isTraceEnabled()) log.trace("Found method in 'using' import: " + identifier);
947+
return List.of(element);
948+
}
947949
}
948950

949951
if (log.isTraceEnabled()) log.trace(traceMsg(null));

src/main/java/com/intellij/plugins/haxe/lang/psi/impl/AbstractHaxeTypeDefImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ public AbstractHaxeTypeDefImpl(@NotNull ASTNode node) {
3737
super(node);
3838
}
3939

40+
private HaxeResolveResult targetClass;
41+
4042
public HaxeResolveResult getTargetClass() {
41-
return getTargetClass(new HaxeGenericSpecialization());
43+
if (targetClass != null) return targetClass;
44+
targetClass = getTargetClass(new HaxeGenericSpecialization());
45+
return targetClass;
4246
}
4347

4448
public SpecificHaxeClassReference getTargetClass(HaxeGenericResolver genericResolver) {

src/main/java/com/intellij/plugins/haxe/lang/psi/impl/HaxeReferenceImpl.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import java.util.stream.Collectors;
5454

5555
import static com.intellij.openapi.util.text.StringUtil.defaultIfEmpty;
56+
import static com.intellij.plugins.haxe.model.type.HaxeExpressionEvaluator.searchReferencesForType;
5657
import static com.intellij.plugins.haxe.model.type.SpecificTypeReference.ARRAY;
5758
import static com.intellij.plugins.haxe.model.type.SpecificTypeReference.CLASS;
5859
import static com.intellij.plugins.haxe.util.HaxeDebugLogUtil.traceAs;
@@ -265,7 +266,7 @@ public PsiElement resolveToComponentName() {
265266
final PsiElement result = resolveResults.length != 1 ||
266267
!resolveResults[0].isValidResult() ? null : resolveResults[0].getElement();
267268

268-
if (result != null && result instanceof HaxeNamedComponent namedComponent) {
269+
if (result instanceof HaxeNamedComponent namedComponent) {
269270
return namedComponent.getComponentName();
270271
}
271272

@@ -816,15 +817,17 @@ else if (resolvedType.isFunctionType()) {
816817
}
817818
if (isType(resolve, HaxeParameter.class)) {
818819
// check if type parameters has multiple constraints and try to unify
819-
HaxeTypeTag tag = ((HaxeParameter)resolve).getTypeTag();
820+
HaxeParameter parameter = (HaxeParameter)resolve;
821+
HaxeTypeTag tag = parameter.getTypeTag();
820822
String typeName = tag != null && tag.getTypeOrAnonymous() != null ? tag.getTypeOrAnonymous().getText() : null;
821823
PsiElement parameterList = resolve.getParent();
822-
if (parameterList != null && parameterList.getParent() instanceof HaxeFunctionLiteral literal) {
824+
if (parameterList != null) {
825+
if (parameterList.getParent() instanceof HaxeFunctionLiteral literal) {
823826
// if parameter type is unknown (allowed in function literals) we can try to find it from assignment, ex. callExpression
824827
ResultHolder holder = tryToFindTypeFromCallExpression(literal, resolve);
825828
if (holder != null && !holder.isUnknown()) return holder.getType().asResolveResult();
826829
}
827-
if (parameterList != null && parameterList.getParent() instanceof HaxeMethodDeclaration method) {
830+
else if (parameterList.getParent() instanceof HaxeMethodDeclaration method) {
828831
HaxeGenericParam methodGenericParam = method.getGenericParam();
829832
List<HaxeGenericListPart> methodPartList = methodGenericParam != null ? methodGenericParam.getGenericListPartList() : null;
830833

@@ -891,8 +894,16 @@ else if (typeOrAnonymous.getAnonymousType() != null) {
891894
}
892895
}
893896
}
894-
else {
895-
897+
}
898+
// try to search for usage to determine type
899+
if (tag == null && parameter.getVarInit() == null) {
900+
HaxeComponentName componentName = parameter.getComponentName();
901+
HaxeExpressionEvaluatorContext context = new HaxeExpressionEvaluatorContext(parameterList);
902+
HaxeMethod method = PsiTreeUtil.getParentOfType(parameter, HaxeMethod.class);
903+
ResultHolder holder = searchReferencesForType(componentName, context, null, method == null ? null : method.getBody());
904+
if (!holder.isUnknown()) {
905+
return holder.getType().asResolveResult();
906+
}
896907
}
897908
}
898909
}

0 commit comments

Comments
 (0)