IDEA-75199 Improve chained completion for strings with prefix.

This commit is contained in:
peter
2011-10-17 20:18:21 +02:00
parent 984d7463ac
commit 3807717ee5
8 changed files with 81 additions and 67 deletions

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2000-2011 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.codeInsight.completion;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.util.Ref;
import com.intellij.util.Consumer;
/**
* @author peter
*/
public class JavaBasicToClassNameDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.BASIC ||
parameters.getInvocationCount() != 1 ||
!JavaCompletionContributor.mayStartClassName(result, false) ||
!JavaCompletionContributor.isClassNamePossible(parameters.getPosition())) {
return;
}
final Ref<Boolean> empty = Ref.create(true);
result.runRemainingContributors(parameters, new Consumer<CompletionResult>() {
public void consume(final CompletionResult lookupElement) {
empty.set(false);
result.passResult(lookupElement);
}
});
if (empty.get()) {
JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result),
true, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
if (classElement != null) {
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
}
result.addElement(element);
}
});
}
}
}

View File

@@ -34,7 +34,7 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
public static final ClassConditionKey<JavaChainLookupElement> CLASS_CONDITION_KEY = ClassConditionKey.create(JavaChainLookupElement.class);
private final LookupElement myQualifier;
private JavaChainLookupElement(LookupElement qualifier, LookupElement main) {
public JavaChainLookupElement(LookupElement qualifier, LookupElement main) {
super(main);
myQualifier = qualifier;
}
@@ -149,8 +149,4 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
}
return ((PsiVariable) object).getType();
}
public static LookupElement chainElements(LookupElement qualifier, LookupElement main) {
return new JavaChainLookupElement(qualifier, main);
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2000-2011 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.codeInsight.completion;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.util.Ref;
import com.intellij.util.Consumer;
/**
* @author peter
*/
public class JavaNoVariantsDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
final Ref<Boolean> empty = Ref.create(true);
Consumer<CompletionResult> passResult = new Consumer<CompletionResult>() {
public void consume(final CompletionResult lookupElement) {
empty.set(false);
result.passResult(lookupElement);
}
};
result.runRemainingContributors(parameters, passResult);
if (empty.get()) {
if (parameters.getCompletionType() == CompletionType.BASIC &&
parameters.getInvocationCount() == 1 &&
JavaCompletionContributor.mayStartClassName(result, false) &&
JavaCompletionContributor.isClassNamePossible(parameters.getPosition())) {
JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result),
true, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
if (classElement != null) {
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
}
result.addElement(element);
}
});
} else if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 2) {
result.runRemainingContributors(parameters.withInvocationCount(3), passResult);
}
}
}
}

View File

@@ -218,7 +218,7 @@ public class ReferenceExpressionCompletionContributor {
final PsiElement qualifier = JavaCompletionUtil.getQualifier(reference.getElement());
final PsiType expectedType = parameters.getExpectedType();
if (!OBJECT_METHOD_PATTERN.accepts(object) || allowGetClass(object, parameters)) {
if (!itemType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
if (parameters.getParameters().getInvocationCount() >= 3 || !itemType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
addChainedCallVariants(element, baseItem, result, itemType, expectedType, parameters);
}
}
@@ -405,7 +405,7 @@ public class ReferenceExpressionCompletionContributor {
final ElementFilter filter = getReferenceFilter(place, true);
for (final LookupElement item : completeFinalReference(place, mockRef, filter, parameters)) {
if (shoudChain(place, varType, expectedType, item)) {
result.consume(JavaChainLookupElement.chainElements(qualifierItem, item));
result.consume(new JavaChainLookupElement(qualifierItem, item));
}
}
}

View File

@@ -0,0 +1,8 @@
class Foo {
{
String message = "";
if (message.startsWith(<caret>))
}
}

View File

@@ -0,0 +1,8 @@
class Foo {
{
String message = "";
if (staWi<caret>)
}
}

View File

@@ -117,6 +117,7 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase {
}
public void testDontChainStringMethodsOnString() throws Throwable { doTest(); }
public void testStringMethodsWhenNothingFound() throws Throwable { doTest(); }
public void testDontSuggestTooGenericMethods() throws Throwable {
configure();

View File

@@ -206,7 +206,7 @@
<completion.confidence language="JAVA" implementationClass="com.intellij.codeInsight.completion.AlwaysFocusLookup" id="javaTrue" order="last"/>
<completion.confidence language="JAVA" implementationClass="com.intellij.codeInsight.completion.SkipAutopopupInStrings" id="javaSkipAutopopupInStrings"/>
<completion.contributor language="JAVA" implementationClass="com.intellij.codeInsight.completion.JavaBasicToClassNameDelegator" id="javaBasic2ClassName"
<completion.contributor language="JAVA" implementationClass="com.intellij.codeInsight.completion.JavaNoVariantsDelegator" id="javaBasic2ClassName"
order="first, before javaMemberName"/>
<completion.contributor language="XML" implementationClass="com.intellij.codeInsight.completion.XmlBasicToClassNameDelegator" id="basic2ClassName"
order="first, after xml"/>