word completion in groovy/java string literals (IDEA-61238)

This commit is contained in:
peter
2011-04-14 17:30:09 +02:00
parent e32c7644b5
commit cabb823fd2
7 changed files with 73 additions and 31 deletions

View File

@@ -50,10 +50,7 @@ import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.*;
import static com.intellij.patterns.PsiJavaPatterns.*;
@@ -198,7 +195,6 @@ public class JavaCompletionContributor extends CompletionContributor {
return;
}
final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);
if (ANNOTATION_ATTRIBUTE_NAME.accepts(position)) {
@@ -216,10 +212,17 @@ public class JavaCompletionContributor extends CompletionContributor {
result.addElement(LookupElementBuilder.create("*"));
}
addReferenceVariants(parameters, result, inheritors);
Set<String> usedWords = addReferenceVariants(parameters, result, inheritors);
addKeywords(parameters, result);
if (psiElement().inside(PsiLiteralExpression.class).accepts(position)) {
PsiReference reference = position.getContainingFile().findReferenceAt(parameters.getOffset());
if (reference == null || reference.isSoft()) {
WordCompletionContributor.addWordCompletionVariants(result, parameters, usedWords);
}
}
addAllClasses(parameters, result, inheritors);
result.stopHere();
}
@@ -239,7 +242,8 @@ public class JavaCompletionContributor extends CompletionContributor {
}
}
private static void addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) {
private static Set<String> addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) {
final Set<String> usedWords = new HashSet<String>();
final PsiElement position = parameters.getPosition();
final boolean checkAccess = parameters.getInvocationCount() <= 1;
LegacyCompletionContributor.processReferences(parameters, result, new PairConsumer<PsiReference, CompletionResultSet>() {
@@ -291,19 +295,25 @@ public class JavaCompletionContributor extends CompletionContributor {
LOG.error("Position=" + position + "\n;Reference=" + reference + "\n;variants=" + Arrays.toString(variants));
}
if (completion instanceof LookupElement && !inheritors.alreadyProcessed((LookupElement)completion)) {
usedWords.add(((LookupElement)completion).getLookupString());
result.addElement((LookupElement)completion);
}
else if (completion instanceof PsiClass) {
if (!inheritors.alreadyProcessed((PsiClass)completion)) {
result.addElement(JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true));
JavaPsiClassReferenceElement item = JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true);
usedWords.add(item.getLookupString());
result.addElement(item);
}
}
else {
result.addElement(LookupItemUtil.objectToLookupItem(completion));
LookupElement element = LookupItemUtil.objectToLookupItem(completion);
usedWords.add(element.getLookupString());
result.addElement(element);
}
}
}
});
return usedWords;
}
private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) {

View File

@@ -0,0 +1,3 @@
public class MyClass {
String b = "My<caret>";
}

View File

@@ -0,0 +1,3 @@
public class MyClass {
String b = "MyClass<caret>";
}

View File

@@ -40,17 +40,12 @@ public class WordCompletionTest extends CompletionTestCase {
@Override
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
return new PsiReference[]{new PsiReferenceBase<PsiElement>(element) {
return new PsiReference[]{new PsiReferenceBase<PsiElement>(element, true) {
@Override
public PsiElement resolve() {
return null;
}
@Override
public boolean isSoft() {
return true;
}
@Override
@NotNull
public Object[] getVariants() {
@@ -63,17 +58,12 @@ public class WordCompletionTest extends CompletionTestCase {
@Override
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
return new PsiReference[]{new PsiReferenceBase<PsiElement>(element) {
return new PsiReference[]{new PsiReferenceBase<PsiElement>(element, false) {
@Override
public PsiElement resolve() {
return null;
}
@Override
public boolean isSoft() {
return false;
}
@Override
@NotNull
public Object[] getVariants() {
@@ -89,6 +79,11 @@ public class WordCompletionTest extends CompletionTestCase {
checkResultByFile(BASE_PATH + "3_after.java");
}
public void testInJavaLiterals() throws Exception {
configureByFile(BASE_PATH + "InJavaLiterals.java");
checkResultByFile(BASE_PATH + "InJavaLiterals_after.java");
}
public void testComments() throws Throwable {
configureByFile(BASE_PATH + "4.java");
checkResultByFile(BASE_PATH + "4_after.java");

View File

@@ -39,6 +39,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Consumer;
import com.intellij.util.PairConsumer;
import com.intellij.util.ProcessingContext;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
@@ -48,6 +49,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
@@ -63,7 +65,8 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
import static com.intellij.patterns.PsiJavaPatterns.elementType;
import static com.intellij.util.containers.CollectionFactory.hashMap;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.*;
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.SEPARATORS;
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.WHITE_SPACES_OR_COMMENTS;
/**
* @author ilyas
@@ -233,8 +236,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
}
});
extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider<CompletionParameters>() {
extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider<CompletionParameters>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@@ -292,6 +294,25 @@ public class GroovyCompletionContributor extends CompletionContributor {
}
});
extend(CompletionType.BASIC, psiElement().withParent(GrLiteral.class), new CompletionProvider<CompletionParameters>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@NotNull final CompletionResultSet result) {
final Set<String> usedWords = new THashSet<String>();
result.runRemainingContributors(parameters, new Consumer<LookupElement>() {
public void consume(LookupElement element) {
result.addElement(element);
usedWords.add(element.getLookupString());
}
});
PsiReference reference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
if (reference == null || reference.isSoft()) {
WordCompletionContributor.addWordCompletionVariants(result, parameters, usedWords);
}
}
});
}
private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) {

View File

@@ -604,13 +604,6 @@ def foo(def a) {2}
return foo()"""
}
void checkCompletion(String before, String type, String after) {
myFixture.configureByText("a.groovy", before)
myFixture.completeBasic()
myFixture.type(type)
myFixture.checkResult(after)
}
public void testFinishClassNameWithSquareBracket() {
myFixture.addClass("class AbcdClass {}; class AbcdeClass {}")
checkCompletion("Abcd<caret>", '[', "AbcdClass[<caret>]")
@@ -674,6 +667,9 @@ a.<caret>""")
return completion.find {println it.lookupString;itemToCheck == it.lookupString}
}
public void testWordCompletionInLiterals() {
checkSingleItemCompletion('def foo = "fo<caret>"', 'def foo = "foo<caret>"')
}
public void testShowAccessor() {
assertNotNull doContainsTest("getFoo", """

View File

@@ -48,4 +48,18 @@ abstract public class GroovyCompletionTestBase extends LightCodeInsightFixtureTe
assertNotNull(list);
UsefulTestCase.assertOrderedEquals(list, variants);
}
public void checkCompletion(String before, String type, String after) {
myFixture.configureByText("a.groovy", before);
myFixture.completeBasic();
myFixture.type(type);
myFixture.checkResult(after);
}
public void checkSingleItemCompletion(String before, String after) {
myFixture.configureByText("a.groovy", before);
myFixture.completeBasic();
myFixture.checkResult(after);
}
}