IDEA-50631 Chaining second smart completion should suggest possible one-element arrays as qualifier

This commit is contained in:
peter
2012-03-06 20:30:18 +04:00
parent e81cb911e7
commit 8ec30835fd
5 changed files with 49 additions and 18 deletions
@@ -130,7 +130,9 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
return true;
}
if (expr instanceof PsiReferenceExpression || expr instanceof PsiMethodCallExpression) {
if (expr instanceof PsiJavaCodeReferenceElement ||
expr instanceof PsiMethodCallExpression ||
expr instanceof PsiArrayAccessExpression) {
return false;
}
@@ -49,9 +49,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
@@ -126,8 +124,15 @@ public class ReferenceExpressionCompletionContributor {
final Set<LookupElement> base =
JavaSmartCompletionContributor.completeReference(element, reference, filter, false, true, parameters.getParameters(), null);
for (final LookupElement item : base) {
addSingleArrayElementAccess(element, item, parameters, result);
for (final LookupElement item : new LinkedHashSet<LookupElement>(base)) {
ExpressionLookupItem access = getSingleArrayElementAccess(element, item);
if (access != null) {
base.add(access);
PsiType type = access.getType();
if (type != null && parameters.getExpectedType().isAssignableFrom(type)) {
result.consume(access);
}
}
}
if (secondTime) {
@@ -218,24 +223,25 @@ public class ReferenceExpressionCompletionContributor {
return used;
}
private static void addSingleArrayElementAccess(PsiElement element, LookupElement item, JavaSmartCompletionParameters parameters,
Consumer<LookupElement> result) {
@Nullable
private static ExpressionLookupItem getSingleArrayElementAccess(PsiElement element, LookupElement item) {
if (item.getObject() instanceof PsiLocalVariable) {
final PsiLocalVariable variable = (PsiLocalVariable)item.getObject();
final PsiType type = variable.getType();
if (type instanceof PsiArrayType && parameters.getExpectedType().isAssignableFrom(((PsiArrayType)type).getComponentType())) {
final PsiExpression expression = variable.getInitializer();
if (expression instanceof PsiNewExpression) {
final PsiNewExpression newExpression = (PsiNewExpression)expression;
final PsiExpression[] dimensions = newExpression.getArrayDimensions();
if (dimensions.length == 1 && "1".equals(dimensions[0].getText()) && newExpression.getArrayInitializer() == null) {
final String text = variable.getName() + "[0]";
final PsiExpression conversion = createExpression(text, element);
result.consume(new ExpressionLookupItem(conversion).setIcon(variable.getIcon(Iconable.ICON_FLAG_VISIBILITY)));
}
final PsiExpression expression = variable.getInitializer();
if (type instanceof PsiArrayType && expression instanceof PsiNewExpression) {
final PsiNewExpression newExpression = (PsiNewExpression)expression;
final PsiExpression[] dimensions = newExpression.getArrayDimensions();
if (dimensions.length == 1 && "1".equals(dimensions[0].getText()) && newExpression.getArrayInitializer() == null) {
final String text = variable.getName() + "[0]";
final PsiExpression conversion = createExpression(text, element);
ExpressionLookupItem result = new ExpressionLookupItem(conversion);
result.setIcon(variable.getIcon(Iconable.ICON_FLAG_VISIBILITY));
return result;
}
}
}
return null;
}
private static PsiExpression createExpression(String text, PsiElement element) {
@@ -0,0 +1,11 @@
class Bar {
Goo getGoo();
}
class Goo {}
class Foo {
{
Bar[] ref = new Bar[1];
Goo g = ref[0].getGoo();<caret>
}
}
@@ -0,0 +1,11 @@
class Bar {
Goo getGoo();
}
class Goo {}
class Foo {
{
Bar[] ref = new Bar[1];
Goo g = <caret>
}
}
@@ -23,6 +23,7 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase {
public void testMethodAsQualifier() throws Throwable { doTest(); }
public void testFieldAsQualifier() throws Throwable { doTest(); }
public void testArrayRefAsQualifier() throws Throwable { doTest(); }
public void testMethodWithParams() throws Throwable { doTest(); }
public void testMergeMethods() throws Throwable { doTest(); }