24
24
import com .intellij .plugins .haxe .util .HaxeResolveUtil ;
25
25
import com .intellij .psi .PsiElement ;
26
26
import com .intellij .psi .util .PsiTreeUtil ;
27
+ import lombok .CustomLog ;
27
28
import org .jetbrains .annotations .NotNull ;
28
29
import org .jetbrains .annotations .Nullable ;
29
30
30
31
import java .util .LinkedHashMap ;
31
32
import java .util .Map ;
32
33
import java .util .Objects ;
34
+ import java .util .Stack ;
33
35
34
36
/**
35
37
* @author: Fedor.Korotkov
36
38
*/
39
+ @ CustomLog
37
40
public class HaxeGenericSpecialization implements Cloneable {
38
41
39
42
public static final HaxeGenericSpecialization EMPTY = new HaxeGenericSpecialization () {
@@ -80,6 +83,10 @@ protected HaxeGenericSpecialization(LinkedHashMap<String, HaxeResolveResult> map
80
83
this .map = map ;
81
84
}
82
85
86
+ // TODO: temp workaround to stop overflow issue in closed source (have not yet found way to reproduce)
87
+ // it seems to be related to function types and resolving type parameters?
88
+ private static ThreadLocal <Stack <PsiElement >> referencesProcessing = ThreadLocal .withInitial (Stack ::new );
89
+
83
90
/**
84
91
* @return the values in this specialization as a HaxeGenericResolver.
85
92
**/
@@ -93,6 +100,7 @@ public HaxeGenericResolver toGenericResolver(@Nullable PsiElement element) {
93
100
*
94
101
* A third would be to remove HaxeGenericResolver altogether and make the models use this class.
95
102
*/
103
+ Stack <PsiElement > elements = referencesProcessing .get ();
96
104
if (null == element ) {
97
105
element = SpecificTypeReference .createUnknownContext ();
98
106
}
@@ -103,21 +111,43 @@ public HaxeGenericResolver toGenericResolver(@Nullable PsiElement element) {
103
111
for (String key : innerMap .keySet ()) {
104
112
HaxeResolveResult resolveResult = innerMap .get (key );
105
113
106
- ResultHolder resultHolder ;
114
+ ResultHolder resultHolder = null ;
115
+
107
116
if (resolveResult .isFunctionType ()) {
108
117
HaxeFunctionType functionType = resolveResult .getFunctionType ();
109
- resultHolder = resolveResult .getSpecificFunctionReference (functionType , null ).createHolder ();
110
- }else if (resolveResult .isHaxeClass ()) {
118
+ if (!elements .contains (functionType )) {
119
+ try {
120
+ elements .add (functionType );
121
+ resultHolder = resolveResult .getSpecificFunctionReference (functionType , null ).createHolder ();
122
+ } finally {
123
+ elements .pop ();
124
+ }
125
+ }else {
126
+ log .warn ("Overflow prevention" );
127
+ }
128
+ }
129
+ else if (resolveResult .isHaxeClass ()) {
111
130
HaxeClass haxeClass = resolveResult .getHaxeClass ();
112
- resultHolder = resolveResult .getSpecificClassReference (haxeClass , null ).createHolder ();
113
- }else {
131
+ if (!elements .contains (haxeClass )) {
132
+ try {
133
+ elements .add (haxeClass );
134
+ resultHolder = resolveResult .getSpecificClassReference (haxeClass , null ).createHolder ();
135
+ } finally {
136
+ elements .pop ();
137
+ }
138
+ }else {
139
+ log .warn ("Overflow prevention" );
140
+ }
141
+ }
142
+ if (resultHolder == null ) {
114
143
HaxeClass haxeClass = SpecificHaxeClassReference .getUnknown (element ).getHaxeClass ();
115
144
resultHolder = resolveResult .getSpecificClassReference (haxeClass , null ).createHolder ();
116
145
}
117
146
118
147
resolver .add (key , resultHolder , ResolveSource .CLASS_TYPE_PARAMETER );
119
148
}
120
149
return resolver ;
150
+
121
151
}
122
152
123
153
@ NotNull
0 commit comments