IDEA-126013 fix SOE : maps and lists declared recursively should not fail type inference into recursion

This commit is contained in:
Max Medvedev
2014-06-10 15:50:32 +04:00
parent 75e06bf181
commit acf850e254
5 changed files with 51 additions and 9 deletions
@@ -183,4 +183,9 @@ public abstract class GrMapType extends GrLiteralClassType {
public static GrMapType createFromNamedArgs(PsiElement context, GrNamedArgument[] args) {
return new GrMapTypeFromNamedArgs(context, args);
}
@Override
public String toString() {
return "map type";
}
}
@@ -15,7 +15,9 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.VolatileNotNullLazyValue;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaPsiFacade;
@@ -50,7 +52,7 @@ public class GrMapTypeFromNamedArgs extends GrMapType {
return ContainerUtil.map(myOtherEntries, new Function<Couple<GrExpression>, Couple<PsiType>>() {
@Override
public Couple<PsiType> fun(Couple<GrExpression> pair) {
return Couple.of(pair.first.getType(), pair.second.getType());
return Couple.of(inferTypePreventingRecursion(pair.first), inferTypePreventingRecursion(pair.second));
}
});
}
@@ -62,7 +64,7 @@ public class GrMapTypeFromNamedArgs extends GrMapType {
protected Map<String, PsiType> compute() {
HashMap<String, PsiType> result = ContainerUtil.newHashMap();
for (Map.Entry<String, GrExpression> entry : myStringEntries.entrySet()) {
result.put(entry.getKey(), entry.getValue().getType());
result.put(entry.getKey(), inferTypePreventingRecursion(entry.getValue()));
}
return result;
}
@@ -99,7 +101,7 @@ public class GrMapTypeFromNamedArgs extends GrMapType {
@Override
public PsiType getTypeByStringKey(String key) {
GrExpression expression = myStringEntries.get(key);
return expression != null ? expression.getType() : null;
return expression != null ? inferTypePreventingRecursion(expression) : null;
}
@NotNull
@@ -121,7 +123,7 @@ public class GrMapTypeFromNamedArgs extends GrMapType {
result.add(GroovyPsiManager.getInstance(myFacade.getProject()).createTypeByFQClassName(CommonClassNames.JAVA_LANG_STRING, getResolveScope()));
}
for (Couple<GrExpression> entry : myOtherEntries) {
result.add(entry.first.getType());
result.add(inferTypePreventingRecursion(entry.first));
}
result.remove(null);
return result.toArray(createArray(result.size()));
@@ -132,15 +134,25 @@ public class GrMapTypeFromNamedArgs extends GrMapType {
protected PsiType[] getAllValueTypes() {
Set<PsiType> result = ContainerUtil.newHashSet();
for (GrExpression expression : myStringEntries.values()) {
result.add(expression.getType());
result.add(inferTypePreventingRecursion(expression));
}
for (Couple<GrExpression> entry : myOtherEntries) {
result.add(entry.second.getType());
result.add(inferTypePreventingRecursion(entry.second));
}
result.remove(null);
return result.toArray(createArray(result.size()));
}
@Nullable
private static PsiType inferTypePreventingRecursion(final GrExpression expression) {
return RecursionManager.doPreventingRecursion(expression, false, new Computable<PsiType>() {
@Override
public PsiType compute() {
return expression.getType();
}
});
}
@NotNull
@Override
protected List<Couple<PsiType>> getOtherEntries() {
@@ -17,6 +17,8 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.search.GlobalSearchScope;
@@ -215,8 +217,13 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
protected PsiType[] inferComponents() {
return ContainerUtil.map(initializers, new Function<GrExpression, PsiType>() {
@Override
public PsiType fun(GrExpression expression) {
return expression.getType();
public PsiType fun(final GrExpression expression) {
return RecursionManager.doPreventingRecursion(expression, false, new Computable<PsiType>() {
@Override
public PsiType compute() {
return expression.getType();
}
});
}
}, new PsiType[initializers.length]);
}
@@ -747,7 +747,7 @@ public class TypesUtil {
}
@Nullable
public static PsiType inferAnnotationMemberValueType(GrAnnotationMemberValue value) {
public static PsiType inferAnnotationMemberValueType(final GrAnnotationMemberValue value) {
if (value instanceof GrExpression) {
return ((GrExpression)value).getType();
}
@@ -696,4 +696,22 @@ class Any {
doExprTest('1f/2.4', 'java.lang.Double')
}
void testRecursionWithMaps() {
doTest('''
def foo(Map map) {
while(true)
ma<caret>p = [a:map]
}
''', 'java.util.Map<java.lang.String, java.util.Map>')
}
void testRecursionWithLists() {
doTest('''
def foo(List list) {
while(true)
lis<caret>t = [list]
}
''', 'java.util.ArrayList<java.util.List>')
}
}