IDEA-106730 Java completion: 'instanceof' is not suggested if an operand is unresolved

This commit is contained in:
peter
2013-05-06 19:07:56 +02:00
parent 36a7a0702d
commit a675c5f31c
4 changed files with 15 additions and 63 deletions
@@ -29,7 +29,6 @@ import com.intellij.psi.*;
import com.intellij.psi.filters.*;
import com.intellij.psi.filters.classes.EnumOrAnnotationTypeFilter;
import com.intellij.psi.filters.classes.InterfaceFilter;
import com.intellij.psi.filters.element.ReferenceOnFilter;
import com.intellij.psi.filters.getters.JavaMembersGetter;
import com.intellij.psi.filters.position.*;
import com.intellij.psi.impl.source.jsp.jspJava.JspClassLevelDeclarationStatement;
@@ -48,16 +47,6 @@ public class JavaCompletionData extends JavaAwareCompletionData {
public static final ElementPattern<PsiElement> AFTER_DOT = psiElement().afterLeaf(".");
private static final LeftNeighbour INSTANCEOF_PLACE = new LeftNeighbour(new OrFilter(
new ReferenceOnFilter(new ClassFilter(PsiVariable.class)),
new TextFilter(PsiKeyword.THIS),
new AndFilter(new TextFilter(")"), new ParentElementFilter(new AndFilter(
new ClassFilter(PsiTypeCastExpression.class, false),
new OrFilter(
new ParentElementFilter(new ClassFilter(PsiExpression.class)),
new ClassFilter(PsiExpression.class))))),
new AndFilter(new TextFilter("]"), new ParentElementFilter(new ClassFilter(PsiArrayAccessExpression.class)))));
public static final PsiJavaElementPattern.Capture<PsiElement> VARIABLE_AFTER_FINAL =
psiElement().afterLeaf(PsiKeyword.FINAL).inside(PsiDeclarationStatement.class);
@@ -517,7 +506,7 @@ public class JavaCompletionData extends JavaAwareCompletionData {
if (JavaSmartCompletionContributor.INSIDE_EXPRESSION.accepts(position) &&
!AFTER_DOT.accepts(position) &&
!(position.getParent() instanceof PsiLiteralExpression)) {
addExpectedTypeMembers(parameters, result, position);
addExpectedTypeMembers(parameters, result);
if (SameSignatureCallParametersProvider.IN_CALL_ARGUMENT.accepts(position)) {
new SameSignatureCallParametersProvider().addCompletions(parameters, new ProcessingContext(), result);
}
@@ -535,7 +524,11 @@ public class JavaCompletionData extends JavaAwareCompletionData {
}
public static boolean isInstanceofPlace(PsiElement position) {
return INSTANCEOF_PLACE.isAcceptable(position, position);
PsiElement prev = PsiTreeUtil.prevVisibleLeaf(position);
if (prev == null) return false;
PsiExpression expr = PsiTreeUtil.getParentOfType(prev, PsiExpression.class);
return expr != null && expr.getTextRange().getEndOffset() == prev.getTextRange().getEndOffset();
}
public static boolean isSuitableForClass(PsiElement position) {
@@ -558,7 +551,7 @@ public class JavaCompletionData extends JavaAwareCompletionData {
return END_OF_BLOCK.isAcceptable(position, position);
}
static void addExpectedTypeMembers(CompletionParameters parameters, final CompletionResultSet result, PsiElement position) {
static void addExpectedTypeMembers(CompletionParameters parameters, final CompletionResultSet result) {
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
new JavaMembersGetter(info.getDefaultType(), parameters).addMembers(parameters.getInvocationCount() > 1, result);
}
@@ -1,49 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.filters.element;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiJavaReference;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.position.PositionElementFilter;
import com.intellij.util.ReflectionCache;
/**
* Created by IntelliJ IDEA.
* User: ik
* Date: 07.02.2003
* Time: 17:25:04
* To change this template use Options | File Templates.
*/
public class ReferenceOnFilter extends PositionElementFilter{
public ReferenceOnFilter(ElementFilter filter){
setFilter(filter);
}
@Override
public boolean isClassAcceptable(Class hintClass){
return ReflectionCache.isAssignable(PsiJavaCodeReferenceElement.class, hintClass);
}
@Override
public boolean isAcceptable(Object element, PsiElement context){
if (!(element instanceof PsiElement)) return false;
PsiElement parent = ((PsiElement) element).getParent();
return parent instanceof PsiJavaCodeReferenceElement &&
getFilter().isAcceptable(((PsiJavaReference)parent).advancedResolve(true).getElement(), context);
}
}
@@ -0,0 +1,7 @@
class Foo {
void test() {
if (o <caret>) {
}
}
}
@@ -105,6 +105,7 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
public void testNullInMethodCall2() throws Exception { doTest(false); }
public void testNewInMethodRefs() throws Exception { doTest(1, "new"); }
public void testSpaceAfterInstanceof() throws Exception { doTest(false); }
public void testInstanceofAfterUnresolved() throws Exception { doTest(1, "instanceof"); }
public void testAbstractInInterface() throws Exception { doTest(1, "abstract"); }
public void testCharInAnnotatedParameter() throws Exception { doTest(1, "char"); }
public void testReturnInTernary() throws Exception { doTest(1, "return"); }