diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fc3e9b6b..a85803380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ # Changelog +## 1.4.43 +* Adding overflow guard when converting GenericSpecialization to genericResolver ## 1.4.42 * Bugfix: Function bindings was incorrectly treated as static extensions * Bugfix: Stack overflow when resolving expression type diff --git a/gradle.properties b/gradle.properties index 5b45b6d1c..878259b59 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ pluginName = Haxe Toolkit Support pluginRepositoryUrl = https://github.com/HaxeFoundation/intellij-haxe # SemVer format -> https://semver.org -pluginVersion = 1.4.42 +pluginVersion = 1.4.43 # IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties platformType = IU diff --git a/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeGenericSpecialization.java b/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeGenericSpecialization.java index 8aacbb5be..cba61263f 100644 --- a/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeGenericSpecialization.java +++ b/src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeGenericSpecialization.java @@ -24,16 +24,19 @@ import com.intellij.plugins.haxe.util.HaxeResolveUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; +import lombok.CustomLog; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; +import java.util.Stack; /** * @author: Fedor.Korotkov */ +@CustomLog public class HaxeGenericSpecialization implements Cloneable { public static final HaxeGenericSpecialization EMPTY = new HaxeGenericSpecialization() { @@ -80,6 +83,10 @@ protected HaxeGenericSpecialization(LinkedHashMap map this.map = map; } + // TODO: temp workaround to stop overflow issue in closed source (have not yet found way to reproduce) + // it seems to be related to function types and resolving type parameters? + private static ThreadLocal> referencesProcessing = ThreadLocal.withInitial(Stack::new); + /** * @return the values in this specialization as a HaxeGenericResolver. **/ @@ -93,6 +100,7 @@ public HaxeGenericResolver toGenericResolver(@Nullable PsiElement element) { * * A third would be to remove HaxeGenericResolver altogether and make the models use this class. */ + Stack elements = referencesProcessing.get(); if (null == element) { element = SpecificTypeReference.createUnknownContext(); } @@ -103,14 +111,35 @@ public HaxeGenericResolver toGenericResolver(@Nullable PsiElement element) { for (String key : innerMap.keySet()) { HaxeResolveResult resolveResult = innerMap.get(key); - ResultHolder resultHolder; + ResultHolder resultHolder = null; + if (resolveResult.isFunctionType()) { HaxeFunctionType functionType = resolveResult.getFunctionType(); - resultHolder = resolveResult.getSpecificFunctionReference(functionType, null).createHolder(); - }else if (resolveResult.isHaxeClass()) { + if (!elements.contains(functionType)) { + try { + elements.add(functionType); + resultHolder = resolveResult.getSpecificFunctionReference(functionType, null).createHolder(); + } finally { + elements.pop(); + } + }else { + log.warn("Overflow prevention"); + } + } + else if (resolveResult.isHaxeClass()) { HaxeClass haxeClass = resolveResult.getHaxeClass(); - resultHolder = resolveResult.getSpecificClassReference(haxeClass, null).createHolder(); - }else { + if (!elements.contains(haxeClass)) { + try { + elements.add(haxeClass); + resultHolder = resolveResult.getSpecificClassReference(haxeClass, null).createHolder(); + } finally { + elements.pop(); + } + }else { + log.warn("Overflow prevention"); + } + } + if (resultHolder == null) { HaxeClass haxeClass = SpecificHaxeClassReference.getUnknown(element).getHaxeClass(); resultHolder = resolveResult.getSpecificClassReference(haxeClass, null).createHolder(); } @@ -118,6 +147,7 @@ public HaxeGenericResolver toGenericResolver(@Nullable PsiElement element) { resolver.add(key, resultHolder, ResolveSource.CLASS_TYPE_PARAMETER); } return resolver; + } @NotNull