mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-52789: Groovy map literals should have LinkedHashMap type
This commit is contained in:
+16
-5
@@ -24,7 +24,6 @@ import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mCOMMA;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
|
||||
@@ -40,6 +39,8 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpre
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mCOMMA;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
*/
|
||||
@@ -89,6 +90,7 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
|
||||
}
|
||||
|
||||
private static class MyTypesCalculator implements Function<GrListOrMapImpl, PsiType> {
|
||||
@Nullable
|
||||
public PsiType fun(GrListOrMapImpl listOrMap) {
|
||||
final GlobalSearchScope scope = listOrMap.getResolveScope();
|
||||
if (listOrMap.isMap()) {
|
||||
@@ -109,7 +111,10 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
|
||||
|
||||
@Nullable
|
||||
private static PsiClassType inferMapInitializerType(GrListOrMapImpl listOrMap, JavaPsiFacade facade, GlobalSearchScope scope) {
|
||||
PsiClass mapClass = facade.findClass("java.util.Map", scope);
|
||||
PsiClass mapClass = facade.findClass("java.util.LinkedHashMap", scope);
|
||||
if (mapClass == null) {
|
||||
mapClass = facade.findClass(CommonClassNames.JAVA_UTIL_MAP, scope);
|
||||
}
|
||||
PsiElementFactory factory = facade.getElementFactory();
|
||||
if (mapClass != null) {
|
||||
PsiTypeParameter[] typeParameters = mapClass.getTypeParameters();
|
||||
@@ -146,15 +151,20 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
|
||||
if (labels.length == 0) return null;
|
||||
PsiType result = null;
|
||||
PsiManager manager = labels[0].getManager();
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(labels[0].getProject());
|
||||
for (GrArgumentLabel label : labels) {
|
||||
PsiElement el = label.getNameElement();
|
||||
final PsiType other;
|
||||
PsiType other;
|
||||
if (el instanceof GrParenthesizedExpression) {
|
||||
other = ((GrParenthesizedExpression)el).getType();
|
||||
}
|
||||
else {
|
||||
if (el.getNode() != null) {
|
||||
other = TypesUtil.getPsiType(el, el.getNode().getElementType());
|
||||
final ASTNode node = el.getNode();
|
||||
if (node != null) {
|
||||
other = TypesUtil.getPsiType(el, node.getElementType());
|
||||
if (other == null) {
|
||||
other = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_STRING, el.getResolveScope());
|
||||
}
|
||||
}
|
||||
else {
|
||||
other = null;
|
||||
@@ -186,6 +196,7 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType getLeastUpperBound(PsiType result, PsiType other, PsiManager manager) {
|
||||
if (other == null) return result;
|
||||
if (result == null) result = other;
|
||||
|
||||
+4
-4
@@ -222,7 +222,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
|
||||
if (getParent() instanceof GrReferenceExpression) {
|
||||
result = facade.getElementFactory().createType((PsiClass) resolved);
|
||||
} else {
|
||||
PsiClass javaLangClass = facade.findClass("java.lang.Class", getResolveScope());
|
||||
PsiClass javaLangClass = facade.findClass(CommonClassNames.JAVA_LANG_CLASS, getResolveScope());
|
||||
if (javaLangClass != null) {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
final PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
|
||||
@@ -239,14 +239,14 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
|
||||
} else
|
||||
if (resolved instanceof PsiMethod && !GroovyPsiManager.isTypeBeingInferred(resolved)) {
|
||||
if (dotType == GroovyTokenTypes.mMEMBER_POINTER) {
|
||||
return facade.getElementFactory().createTypeByFQClassName("groovy.lang.Closure", getResolveScope());
|
||||
return facade.getElementFactory().createTypeByFQClassName(GrClosableBlock.GROOVY_LANG_CLOSURE, getResolveScope());
|
||||
}
|
||||
PsiMethod method = (PsiMethod) resolved;
|
||||
if (PropertyUtil.isSimplePropertySetter(method) && !method.getName().equals(getReferenceName())) {
|
||||
result = method.getParameterList().getParameters()[0].getType();
|
||||
} else {
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null && "java.lang.Object".equals(containingClass.getQualifiedName()) &&
|
||||
if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) &&
|
||||
"getClass".equals(method.getName())) {
|
||||
result = getTypeForObjectGetClass(facade, method);
|
||||
} else {
|
||||
@@ -283,7 +283,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
|
||||
PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
|
||||
PsiClass clazz = qResult.getElement();
|
||||
if (clazz != null) {
|
||||
PsiClass mapClass = facade.findClass("java.util.Map", getResolveScope());
|
||||
PsiClass mapClass = facade.findClass(CommonClassNames.JAVA_UTIL_MAP, getResolveScope());
|
||||
if (mapClass != null && mapClass.getTypeParameters().length == 2) {
|
||||
PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
|
||||
if (substitutor != null) {
|
||||
|
||||
+20
-11
@@ -17,16 +17,16 @@
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.PsiArrayType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
@@ -74,9 +74,21 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
|
||||
argTypes[i] = argType;
|
||||
}
|
||||
|
||||
final PsiType overloadedOperatorType = TypesUtil.getOverloadedOperatorType(thisType, "getAt", this, argTypes);
|
||||
if (overloadedOperatorType!=null) {
|
||||
return overloadedOperatorType;
|
||||
if (thisType instanceof GrTupleType) {
|
||||
PsiType[] types = ((GrTupleType)thisType).getParameters();
|
||||
return types.length == 1 ? types[0] : null;
|
||||
}
|
||||
|
||||
PsiType overloadedOperatorType = null;
|
||||
final GroovyResolveResult[] candidates = TypesUtil.getOverloadedOperatorCandidates(thisType, "getAt", this, argTypes);
|
||||
if (candidates.length == 1) {
|
||||
final PsiElement element = candidates[0].getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
overloadedOperatorType = candidates[0].getSubstitutor().substitute(((PsiMethod)element).getReturnType());
|
||||
if (overloadedOperatorType != null && !(element instanceof GrGdkMethod)) { //gdk 'getAt' methods don't have information about type parameters
|
||||
return overloadedOperatorType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (thisType instanceof PsiArrayType) {
|
||||
@@ -84,11 +96,6 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
|
||||
return TypesUtil.boxPrimitiveType(componentType, getManager(), getResolveScope());
|
||||
}
|
||||
|
||||
if (thisType instanceof GrTupleType) {
|
||||
PsiType[] types = ((GrTupleType)thisType).getParameters();
|
||||
return types.length == 1 ? types[0] : null;
|
||||
}
|
||||
|
||||
if (InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_LIST)) {
|
||||
PsiType iterType = PsiUtil.extractIterableTypeParameter(thisType, true);
|
||||
if (iterType != null) return iterType;
|
||||
@@ -97,6 +104,8 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
|
||||
if (InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_MAP)) {
|
||||
return PsiUtil.substituteTypeParameter(thisType, CommonClassNames.JAVA_UTIL_MAP, 1, true);
|
||||
}
|
||||
|
||||
return overloadedOperatorType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -222,4 +222,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase {
|
||||
}
|
||||
|
||||
public void testSuperConstructorInvocation() throws Exception {doTest();}
|
||||
|
||||
public void testIndexPropertyAccess() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class X extends HashMap<Integer, Integer> {
|
||||
def getAt(def k) {
|
||||
return "string"
|
||||
}
|
||||
}
|
||||
|
||||
def x = new X();
|
||||
print x[2].concat("a")
|
||||
Reference in New Issue
Block a user