Groovy: resolve incomplete code in index property

This commit is contained in:
Max Medvedev
2012-09-28 09:05:18 +03:00
parent 8be94b3b92
commit fe2eb0bc53
3 changed files with 45 additions and 25 deletions
@@ -23,10 +23,7 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NullableFunction;
import com.intellij.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
@@ -40,9 +37,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
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.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@@ -211,8 +208,20 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
if (candidates.length != 1) {
final GrTupleType tupleType = new GrTupleType(argTypes, JavaPsiFacade.getInstance(getProject()), resolveScope);
candidates = ResolveUtil.getMethodCandidates(thisType, name, this, tupleType);
final GroovyResolveResult[] tupleCandidates = ResolveUtil.getMethodCandidates(thisType, name, this, tupleType);
if (incompleteCode) {
candidates = ArrayUtil.mergeArrays(candidates, tupleCandidates, new ArrayFactory<GroovyResolveResult>() {
@Override
public GroovyResolveResult[] create(int count) {
return new GroovyResolveResult[count];
}
});
}
else {
candidates = tupleCandidates;
}
}
return candidates;
}
@@ -35,7 +35,7 @@ public abstract class GroovyResolveTestCase extends LightGroovyTestCase {
@NonNls protected static final String MARKER = "<ref>";
@Override
protected void setUp() throws Exception {
protected void setUp() {
super.setUp();
if (new File("$myFixture.testDataPath/${getTestName(true)}").exists()) {
myFixture.copyDirectoryToProject(getTestName(true), "");
@@ -34,12 +34,9 @@ import static com.intellij.psi.CommonClassNames.*
* @author ven
*/
public class TypeInferenceTest extends GroovyResolveTestCase {
@Override
protected String getBasePath() {
return TestUtils.getTestDataPath() + "resolve/inference/";
}
final String basePath = TestUtils.testDataPath + "resolve/inference/"
public void testTryFinallyFlow() throws Exception {
public void testTryFinallyFlow() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow/A.groovy").getElement();
final PsiType type = ref.getType();
assertTrue(type instanceof PsiIntersectionType);
@@ -47,77 +44,77 @@ public class TypeInferenceTest extends GroovyResolveTestCase {
assertEquals(conjuncts.length, 2);
}
public void testTryFinallyFlow1() throws Exception {
public void testTryFinallyFlow1() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow1/A.groovy").getElement();
final PsiType type = ref.getType();
assertNotNull(type);
assertTrue(type.equalsToText("java.lang.Integer"));
}
public void testTryFinallyFlow2() throws Exception {
public void testTryFinallyFlow2() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow2/A.groovy").getElement();
final PsiType type = ref.getType();
assertNotNull(type);
assertTrue(type.equalsToText("java.lang.Integer"));
}
public void testThrowVariable() throws Exception {
public void testThrowVariable() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("throwVariable/A.groovy").getElement();
final PsiType type = ref.getType();
assertNotNull(type);
assertEquals("java.lang.Exception", type.getCanonicalText());
}
public void testGrvy852() throws Exception {
public void testGrvy852() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("grvy852/A.groovy").getElement();
final PsiType type = ref.getType();
assertNotNull(type);
assertEquals("java.lang.Object", type.getCanonicalText());
}
public void testGenericMethod() throws Exception {
public void testGenericMethod() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("genericMethod/A.groovy").getElement();
final PsiType type = ref.getType();
assertNotNull(type);
assertEquals("java.util.List<java.lang.String>", type.getCanonicalText());
}
public void testCircular() throws Exception {
public void testCircular() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("circular/A.groovy").getElement();
assertNull(ref.getType());
}
public void testCircular1() throws Exception {
public void testCircular1() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("circular1/A.groovy").getElement();
assertNull(ref.getType());
}
public void testClosure() throws Exception {
public void testClosure() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure/A.groovy").getElement();
assertNotNull(ref.getType());
}
public void testClosure1() throws Exception {
public void testClosure1() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure1/A.groovy").getElement();
assertTrue(ref.getType().equalsToText("java.lang.Integer"));
}
public void testClosure2() throws Exception {
public void testClosure2() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure2/A.groovy").getElement();
assertTrue(ref.getType().equalsToText("java.lang.Integer"));
}
public void testGrvy1209() throws Exception {
public void testGrvy1209() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("grvy1209/A.groovy").getElement();
assertTrue(ref.getType().equalsToText("java.lang.String"));
}
public void testLeastUpperBoundClosureType() throws Exception {
public void testLeastUpperBoundClosureType() {
GrReferenceExpression ref = (GrReferenceExpression)configureByFile("leastUpperBoundClosureType/A.groovy").getElement();
assertInstanceOf(ref.getType(), GrClosureType.class);
}
public void testJavaLangClassType() throws Exception {
public void testJavaLangClassType() {
final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("javaLangClassType/A.groovy").getElement();
assertEquals("java.lang.String", ref.getType().getCanonicalText());
}
@@ -545,6 +542,20 @@ def foo(ii) {
}''', 'java.lang.String'
}
void testIndexProperty() {
doTest('''\
private void getCommonAncestor() {
def c1 = [new File('a')]
for (int i = 0; i < 2; i++) {
if (c1[i] != null) break
def cur = c1[i]
print cu<caret>r
}
}
''', 'java.io.File')
}
private void doTest(String text, String type) {
def file = myFixture.configureByText('_.groovy', text)
def ref = file.findReferenceAt(myFixture.editor.caretModel.offset) as GrReferenceExpression