diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java
index e30d24327ee4..4bf6c6faf70f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java
@@ -19,18 +19,19 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path;
import com.intellij.lang.ASTNode;
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;
+import static com.intellij.psi.util.PsiUtil.substituteTypeParameter;
+import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.getSmartReturnType;
+
/**
* @author ilyas
*/
@@ -74,38 +75,41 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
argTypes[i] = argType;
}
- if (thisType instanceof GrTupleType) {
+ if (thisType instanceof GrTupleType &&
+ argTypes.length == 1 &&
+ TypesUtil.isAssignable(PsiType.INT, argTypes[0], getManager(), getResolveScope())) {
PsiType[] types = ((GrTupleType)thisType).getParameters();
return types.length == 1 ? types[0] : null;
}
PsiType overloadedOperatorType = null;
- final GroovyResolveResult[] candidates = TypesUtil.getOverloadedOperatorCandidates(thisType, "getAt", this, argTypes);
+ GroovyResolveResult[] candidates = TypesUtil.getOverloadedOperatorCandidates(thisType, "getAt", this, argTypes);
+ if (candidates.length != 1) {
+ candidates = TypesUtil.getOverloadedOperatorCandidates(thisType, "getAt", this, new PsiType[]{
+ new GrTupleType(argTypes, JavaPsiFacade.getInstance(getProject()), getResolveScope())});
+ }
if (candidates.length == 1) {
final PsiElement element = candidates[0].getElement();
if (element instanceof PsiMethod) {
- overloadedOperatorType = candidates[0].getSubstitutor().substitute(org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.getSmartReturnType((PsiMethod)element));
- if (overloadedOperatorType != null && !(element instanceof GrGdkMethod)) { //gdk 'getAt' methods don't have information about type parameters
- return overloadedOperatorType;
- }
+ overloadedOperatorType = candidates[0].getSubstitutor().substitute(getSmartReturnType((PsiMethod)element));
}
}
- if (thisType instanceof PsiArrayType) {
- PsiType componentType = ((PsiArrayType)thisType).getComponentType();
- return TypesUtil.boxPrimitiveType(componentType, getManager(), getResolveScope());
+ PsiType componentType = null;
+ if (thisType instanceof PsiArrayType &&
+ argTypes.length == 1 &&
+ TypesUtil.isAssignable(PsiType.INT, argTypes[0], getManager(), getResolveScope())) {
+ componentType = TypesUtil.boxPrimitiveType(((PsiArrayType)thisType).getComponentType(), getManager(), getResolveScope());
+ }
+ else if (InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_MAP) && argTypes.length == 1) {
+ componentType = substituteTypeParameter(thisType, CommonClassNames.JAVA_UTIL_MAP, 1, true);
}
- if (InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_LIST)) {
- PsiType iterType = PsiUtil.extractIterableTypeParameter(thisType, true);
- if (iterType != null) return iterType;
+ if (overloadedOperatorType != null &&
+ (componentType == null || !TypesUtil.isAssignable(overloadedOperatorType, componentType, getManager(), getResolveScope()))) {
+ return overloadedOperatorType;
}
-
- if (InheritanceUtil.isInheritor(thisType, CommonClassNames.JAVA_UTIL_MAP)) {
- return PsiUtil.substituteTypeParameter(thisType, CommonClassNames.JAVA_UTIL_MAP, 1, true);
- }
-
- return overloadedOperatorType;
+ return componentType;
}
}
return null;
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/GrCompletionTestWithLibrary.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/GrCompletionTestWithLibrary.groovy
index 967dcc8d2b23..2297b11c51b9 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/GrCompletionTestWithLibrary.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/GrCompletionTestWithLibrary.groovy
@@ -58,4 +58,5 @@ class GrCompletionTestWithLibrary extends GroovyCompletionTestBase {
public void testCategoryProperty() {doBasicTest()}
public void testMultipleCategories() {doBasicTest()}
+ public void testArrayLikeAccessForList() throws Throwable {doBasicTest(); }
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTest.java
index cbcb20662b39..db2e370bec05 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTest.java
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTest.java
@@ -96,10 +96,6 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase {
doBasicTest();
}
- public void testArrayLikeAccessForList() throws Throwable {
- doBasicTest();
- }
-
public void testArrayLikeAccessForMap() throws Throwable {
doBasicTest();
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java
index 65d2d74e5b97..bfe4adfa098a 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.java
@@ -117,4 +117,9 @@ public class TypeInferenceTest extends GroovyResolveTestCase {
final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("genericWildcard/A.groovy").getElement();
assertEquals("A", ref.getType().getCanonicalText());
}
+
+ public void testArrayLikeAccessWithIntSequence() {
+ final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("arrayLikeAccessWithIntSequence/A.groovy").getElement();
+ assertEquals("java.util.List", ref.getType().getCanonicalText());
+ }
}
diff --git a/plugins/groovy/testdata/groovy/completion/ArrayLikeAccessForList.groovy b/plugins/groovy/testdata/groovy/completionWithLibrary/ArrayLikeAccessForList.groovy
similarity index 100%
rename from plugins/groovy/testdata/groovy/completion/ArrayLikeAccessForList.groovy
rename to plugins/groovy/testdata/groovy/completionWithLibrary/ArrayLikeAccessForList.groovy
diff --git a/plugins/groovy/testdata/groovy/completion/ArrayLikeAccessForList_after.groovy b/plugins/groovy/testdata/groovy/completionWithLibrary/ArrayLikeAccessForList_after.groovy
similarity index 100%
rename from plugins/groovy/testdata/groovy/completion/ArrayLikeAccessForList_after.groovy
rename to plugins/groovy/testdata/groovy/completionWithLibrary/ArrayLikeAccessForList_after.groovy
diff --git a/plugins/groovy/testdata/resolve/inference/arrayLikeAccessWithIntSequence/A.groovy b/plugins/groovy/testdata/resolve/inference/arrayLikeAccessWithIntSequence/A.groovy
new file mode 100644
index 000000000000..d176af95fc38
--- /dev/null
+++ b/plugins/groovy/testdata/resolve/inference/arrayLikeAccessWithIntSequence/A.groovy
@@ -0,0 +1,4 @@
+def foo = [1, 2, 5]
+def list = foo[1, 2]
+
+print l[ist
\ No newline at end of file
]