From ad2301818c7c5613f38e883acca8078e44f524f7 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 19 Oct 2011 12:44:39 +0200 Subject: [PATCH] suggest inheritor members on second completion only, prefer the default collection getters to them --- .../CollectionsUtilityMethodsProvider.java | 4 +++ .../completion/JavaCompletionData.java | 2 +- .../JavaSmartCompletionContributor.java | 5 ++-- ...ariablesLiteralsAndAnnoMethodsWeigher.java | 5 ++++ .../InheritorEnumMembers-out.java | 0 .../{ => second}/InheritorEnumMembers.java | 0 .../{ => second}/InheritorMembers-out.java | 0 .../{ => second}/InheritorMembers.java | 0 .../PreferCollectionsEmptyList.java | 8 ++++++ .../SecondSmartTypeCompletionTest.java | 28 +++++++++++++++---- .../SmartTypeCompletionOrderingTest.groovy | 9 +++++- .../completion/SmartTypeCompletionTest.java | 2 -- .../codeInsight/lookup/LookupItem.java | 4 +-- .../GroovySmartCompletionContributor.java | 2 +- 14 files changed, 54 insertions(+), 15 deletions(-) rename java/java-tests/testData/codeInsight/completion/smartType/{ => second}/InheritorEnumMembers-out.java (100%) rename java/java-tests/testData/codeInsight/completion/smartType/{ => second}/InheritorEnumMembers.java (100%) rename java/java-tests/testData/codeInsight/completion/smartType/{ => second}/InheritorMembers-out.java (100%) rename java/java-tests/testData/codeInsight/completion/smartType/{ => second}/InheritorMembers.java (100%) create mode 100644 java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferCollectionsEmptyList.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java index a18458d5d690..edf3a01d342d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.util.Consumer; import org.jetbrains.annotations.NonNls; @@ -28,6 +29,8 @@ import static com.intellij.psi.CommonClassNames.*; * @author peter */ class CollectionsUtilityMethodsProvider { + public static final Key COLLECTION_FACTORY = Key.create("CollectionFactory"); + public static void addCompletions(@NotNull final JavaSmartCompletionParameters parameters, @NotNull final Consumer result) { final PsiElement element = parameters.getPosition(); @@ -85,6 +88,7 @@ class CollectionsUtilityMethodsProvider { final JavaMethodCallElement item = new JavaMethodCallElement(method, false, false); item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType)); + item.putUserData(COLLECTION_FACTORY, true); result.consume(item); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java index d9b26734fb77..600412bbe329 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -542,7 +542,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{ !(position.getParent() instanceof PsiLiteralExpression) && !(position.getParent().getParent() instanceof PsiSwitchLabelStatement)) { for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) { - new JavaMembersGetter(info.getDefaultType()).addMembers(position, parameters.getInvocationCount() > 0, new Consumer() { + new JavaMembersGetter(info.getDefaultType()).addMembers(position, parameters.getInvocationCount() > 1, new Consumer() { @Override public void consume(LookupElement element) { result.addElement(element); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 32cb6da742ad..6dea9b5e0136 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -223,9 +223,10 @@ public class JavaSmartCompletionContributor extends CompletionContributor { parent != null && !(parent.getParent() instanceof PsiSwitchLabelStatement)) { for (ExpectedTypeInfo info : mergedInfos) { - new JavaMembersGetter(info.getType()).addMembers(position, true, noTypeCheck); + final boolean searchInheritors = params.getInvocationCount() > 1; + new JavaMembersGetter(info.getType()).addMembers(position, searchInheritors, noTypeCheck); if (!info.getDefaultType().equals(info.getType())) { - new JavaMembersGetter(info.getDefaultType()).addMembers(position, true, noTypeCheck); + new JavaMembersGetter(info.getDefaultType()).addMembers(position, searchInheritors, noTypeCheck); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java index 86a2271a181a..5159fb5430db 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java @@ -44,6 +44,7 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupEle qualifiedWithField, qualifiedWithGetter, superMethodParameters, + collectionFactory, normal, nonInitialized, classLiteral, @@ -70,6 +71,10 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupEle if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) { return MyResult.superMethodParameters; } + + if (item.getUserData(CollectionsUtilityMethodsProvider.COLLECTION_FACTORY) != null) { + return MyResult.collectionFactory; + } final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY); if (chain != null) { diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InheritorEnumMembers-out.java b/java/java-tests/testData/codeInsight/completion/smartType/second/InheritorEnumMembers-out.java similarity index 100% rename from java/java-tests/testData/codeInsight/completion/smartType/InheritorEnumMembers-out.java rename to java/java-tests/testData/codeInsight/completion/smartType/second/InheritorEnumMembers-out.java diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InheritorEnumMembers.java b/java/java-tests/testData/codeInsight/completion/smartType/second/InheritorEnumMembers.java similarity index 100% rename from java/java-tests/testData/codeInsight/completion/smartType/InheritorEnumMembers.java rename to java/java-tests/testData/codeInsight/completion/smartType/second/InheritorEnumMembers.java diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InheritorMembers-out.java b/java/java-tests/testData/codeInsight/completion/smartType/second/InheritorMembers-out.java similarity index 100% rename from java/java-tests/testData/codeInsight/completion/smartType/InheritorMembers-out.java rename to java/java-tests/testData/codeInsight/completion/smartType/second/InheritorMembers-out.java diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InheritorMembers.java b/java/java-tests/testData/codeInsight/completion/smartType/second/InheritorMembers.java similarity index 100% rename from java/java-tests/testData/codeInsight/completion/smartType/InheritorMembers.java rename to java/java-tests/testData/codeInsight/completion/smartType/second/InheritorMembers.java diff --git a/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferCollectionsEmptyList.java b/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferCollectionsEmptyList.java new file mode 100644 index 000000000000..2770782a68bc --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferCollectionsEmptyList.java @@ -0,0 +1,8 @@ +public class Aaaaaaa { + + { + java.util.List local = null; + java.util.List l = + } + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java index 988d5f2ae0a2..f70d1d83fb47 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java @@ -48,7 +48,7 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { configure(); assertStringItems("foos().toArray(EMPTY_ARRAY)", "foos().toArray(EMPTY_ARRAY2)"); selectItem(myItems[0]); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); } public void testToArrayGenericArrayCreation() throws Throwable { doTest(); } @@ -62,7 +62,7 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { configure(); assertStringItems("foos().toArray(Bar.EMPTY_ARRAY)", "foos().toArray(Bar.EMPTY_ARRAY2)"); selectItem(myItems[0]); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); } public void testNonInitializedField() throws Throwable { doTest(); } @@ -104,14 +104,14 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { assertEquals("Arrays.asList(f.bar())", ((LookupItem)((LookupElementDecorator)myItems[0]).getDelegate()).getPresentableText()); assertEquals("Arrays.asList(f.foo())", ((LookupItem)((LookupElementDecorator)myItems[1]).getDelegate()).getPresentableText()); selectItem(myItems[1]); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); } public void testRestoreInitialPrefix() throws Throwable { configureByFileNoComplete(BASE_PATH + "/" + getTestName(false) + ".java"); complete(1); assertStringItems("MyEnum.Bar", "MyEnum.Foo"); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); complete(1); assertStringItems("my.getEnum", "MyEnum.Bar", "MyEnum.Foo"); } @@ -155,13 +155,17 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { public void testEmptyListInMethodCall() throws Throwable { configure(); selectItem(myItems[0]); + checkResult(); + } + + private void checkResult() { checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); } public void testSingletonMap() throws Throwable { configure(); selectItem(myItems[0]); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); } protected void checkResultByFile(@NonNls final String filePath) { @@ -174,7 +178,19 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { private void doTest() throws Exception { configure(); - checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-out.java"); + checkResult(); + } + + public void testInheritorMembers() throws Throwable { + configure(); + selectItem(myItems[0]); + checkResult(); + } + + public void testInheritorEnumMembers() throws Throwable { + configure(); + selectItem(myItems[0]); + checkResult(); } @Override diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy index a86eb2b43a57..dcb13ac55001 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy @@ -287,7 +287,14 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { checkPreferredItems(0, "boo", "bar") } - + public void testPreferCollectionsEmptyList() throws Throwable { + myFixture.addClass("package foo; public class FList implements java.util.List { public static FList emptyList() {} }"); + configureNoCompletion(getTestName(false) + ".java"); + myFixture.complete(CompletionType.SMART, 2); + assertPreferredItems(0, "local", "local.subList", "emptyList", "singletonList", "unmodifiableList"); + assert 'Collections.emptyList' in lookup.items[2].allLookupStrings + assert 'FList.emptyList' in lookup.items[5].allLookupStrings + } @Override protected String getBasePath() { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index 104712b8d2a4..70e030234c3e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -1026,8 +1026,6 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { } public void testArrayInitializerBeforeVarargs() throws Throwable { doTest(); } - public void testInheritorMembers() throws Throwable { doTest(); } - public void testInheritorEnumMembers() throws Throwable { doTest(); } public void testDuplicateMembersFromSuperClass() throws Throwable { doTest(); } public void testMemberImportStatically() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index fa3c983a401a..076428bd32a8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -29,12 +29,12 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; -import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -67,7 +67,7 @@ public class LookupItem extends MutableLookupElement implements Comparable private double myPriority; private Map myAttributes = null; public static final LookupItem[] EMPTY_ARRAY = new LookupItem[0]; - private final Set myAllLookupStrings = new THashSet(); + private final Set myAllLookupStrings = new HashSet(); private String myPresentable; private AutoCompletionPolicy myAutoCompletionPolicy = AutoCompletionPolicy.SETTINGS_DEPENDENT; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java index fb7621625435..48ccf2fbdf4a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java @@ -218,7 +218,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor { }; PsiType type = info.getType(); PsiType defType = info.getDefaultType(); - boolean searchInheritors = params.getInvocationCount() > 0; + boolean searchInheritors = params.getInvocationCount() > 1; if (type instanceof PsiClassType) { new GroovyMembersGetter((PsiClassType)type, reference).processMembers(searchInheritors, consumer); }