From 4037871a23658c41f4cf983f4814246bfe4ad96a Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 29 Jan 2014 19:23:36 +0100 Subject: [PATCH] IDEA-119983 Smart type completion mixes order for Color.RED --- .../CollectionsUtilityMethodsProvider.java | 3 --- .../completion/PreferByKindWeigher.java | 15 ++++++++++----- .../ReferenceExpressionCompletionContributor.java | 9 +++++++-- .../psi/filters/getters/MembersGetter.java | 10 +++++----- .../PreferExpectedTypeMembers.java | 14 ++++++++++++++ .../completion/SecondSmartTypeCompletionTest.java | 2 +- .../SmartTypeCompletionOrderingTest.groovy | 9 ++++++++- .../completion/SmartTypeCompletionTest.java | 2 +- 8 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferExpectedTypeMembers.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 9411f764f8df..68893c6c973b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/CollectionsUtilityMethodsProvider.java @@ -17,7 +17,6 @@ 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; @@ -29,7 +28,6 @@ import static com.intellij.psi.CommonClassNames.*; * @author peter */ class CollectionsUtilityMethodsProvider { - public static final Key COLLECTION_FACTORY = Key.create("CollectionFactory"); private final PsiElement myElement; private final PsiType myExpectedType; private final PsiType myDefaultType; @@ -95,7 +93,6 @@ class CollectionsUtilityMethodsProvider { final JavaMethodCallElement item = new JavaMethodCallElement(method, false, false); item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType), myElement); - item.putUserData(COLLECTION_FACTORY, true); myResult.consume(item); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java index 6e2c627dc625..fcd5ff8ada0a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java @@ -112,9 +112,10 @@ public class PreferByKindWeigher extends LookupElementWeigher { qualifiedWithField, qualifiedWithGetter, superMethodParameters, + expectedTypeConstant, normal, collectionFactory, - expectedTypeMember, + expectedTypeMethod, suitableClass, nonInitialized, classLiteral, @@ -147,11 +148,15 @@ public class PreferByKindWeigher extends LookupElementWeigher { } if (myCompletionType == CompletionType.SMART) { - if (item.getUserData(CollectionsUtilityMethodsProvider.COLLECTION_FACTORY) != null) { - return MyResult.collectionFactory; + if (object instanceof PsiMethod) { + PsiClass containingClass = ((PsiMethod)object).getContainingClass(); + if (containingClass != null && CommonClassNames.JAVA_UTIL_COLLECTIONS.equals(containingClass.getQualifiedName())) { + return MyResult.collectionFactory; + } } - if (Boolean.TRUE.equals(item.getUserData(MembersGetter.EXPECTED_TYPE_INHERITOR_MEMBER))) { - return MyResult.expectedTypeMember; + Boolean expectedTypeMember = item.getUserData(MembersGetter.EXPECTED_TYPE_MEMBER); + if (expectedTypeMember != null) { + return expectedTypeMember ? (object instanceof PsiField ? MyResult.expectedTypeConstant : MyResult.expectedTypeMethod) : MyResult.classNameOrGlobalStatic; } final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java index f4adccc7140d..1f951f85cda8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java @@ -491,8 +491,13 @@ public class ReferenceExpressionCompletionContributor { } private static boolean shouldChain(PsiElement element, PsiType qualifierType, PsiType expectedType, LookupElement item) { - if (item.getObject() instanceof PsiMethod) { - final PsiMethod method = (PsiMethod)item.getObject(); + Object object = item.getObject(); + if (object instanceof PsiModifierListOwner && ((PsiModifierListOwner)object).hasModifierProperty(PsiModifier.STATIC)) { + return false; + } + + if (object instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)object; if (psiMethod().withName("toArray").withParameterCount(1) .definedInClass(CommonClassNames.JAVA_UTIL_COLLECTION).accepts(method)) { return false; diff --git a/java/java-impl/src/com/intellij/psi/filters/getters/MembersGetter.java b/java/java-impl/src/com/intellij/psi/filters/getters/MembersGetter.java index 9cb5a212acad..9e13bdc576de 100644 --- a/java/java-impl/src/com/intellij/psi/filters/getters/MembersGetter.java +++ b/java/java-impl/src/com/intellij/psi/filters/getters/MembersGetter.java @@ -44,7 +44,7 @@ import java.util.*; * @author peter */ public abstract class MembersGetter { - public static final Key EXPECTED_TYPE_INHERITOR_MEMBER = Key.create("EXPECTED_TYPE_INHERITOR_MEMBER"); + public static final Key EXPECTED_TYPE_MEMBER = Key.create("EXPECTED_TYPE_MEMBER"); private final Set myImportedStatically = new HashSet(); private final List myPlaceClasses = new ArrayList(); private final List myPlaceMethods = new ArrayList(); @@ -111,12 +111,12 @@ public abstract class MembersGetter { if (mayProcessMembers(psiClass)) { final FilterScopeProcessor declProcessor = new FilterScopeProcessor(TrueFilter.INSTANCE); psiClass.processDeclarations(declProcessor, ResolveState.initial(), null, myPlace); - doProcessMembers(acceptMethods, results, psiType != baseType, declProcessor.getResults()); + doProcessMembers(acceptMethods, results, psiType == baseType, declProcessor.getResults()); String name = psiClass.getName(); if (name != null && searchFactoryMethods) { Collection factoryMethods = JavaStaticMemberTypeIndex.getInstance().getStaticMembers(name, project, scope); - doProcessMembers(acceptMethods, results, psiType != baseType, factoryMethods); + doProcessMembers(acceptMethods, results, false, factoryMethods); } } } @@ -129,7 +129,7 @@ public abstract class MembersGetter { private void doProcessMembers(boolean acceptMethods, Consumer results, - boolean isInheritor, Collection declarations) { + boolean isExpectedTypeMember, Collection declarations) { for (final PsiElement result : declarations) { if (result instanceof PsiMember && !(result instanceof PsiClass)) { final PsiMember member = (PsiMember)result; @@ -144,7 +144,7 @@ public abstract class MembersGetter { final LookupElement item = result instanceof PsiMethod ? createMethodElement((PsiMethod)result) : createFieldElement((PsiField)result); if (item != null) { - item.putUserData(EXPECTED_TYPE_INHERITOR_MEMBER, isInheritor); + item.putUserData(EXPECTED_TYPE_MEMBER, isExpectedTypeMember); results.consume(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(item)); } } diff --git a/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferExpectedTypeMembers.java b/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferExpectedTypeMembers.java new file mode 100644 index 000000000000..bf4b84f16ce5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferExpectedTypeMembers.java @@ -0,0 +1,14 @@ +class MyColor { + static final MyColor RED = null; +} +class Another { + static final MyColor RED = null; +} + +class Foo { + public static final MyColor MARKED_BACKGROUND = new MyColor(); + + { + MyColor color = RED + } +} \ No newline at end of file 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 a25827ac6a60..22ed4e891375 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java @@ -203,7 +203,7 @@ public class SecondSmartTypeCompletionTest extends LightFixtureCompletionTestCas public void testGlobalFactoryMethods() { configure(); - assertStringItems("createExpected", "Constants.SUBSTRING", "createSubGeneric", "createSubRaw", "createSubString"); + assertStringItems("Constants.SUBSTRING", "createExpected", "createSubGeneric", "createSubRaw", "createSubString"); } public void testEmptyMapPresentation() { 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 24604af0f7d9..1aebb295e3ac 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy @@ -149,7 +149,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { } public void testBooleanValueOf() throws Throwable { - checkPreferredItems(0, "b", "valueOf", "valueOf", "Boolean.FALSE", "Boolean.TRUE"); + checkPreferredItems(0, "b", "Boolean.FALSE", "Boolean.TRUE", "equals", "false", "true", "valueOf", "valueOf"); } public void testXmlTagGetAttribute() throws Throwable { @@ -333,6 +333,13 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { assertPreferredItems 0, 'newLinkedSet1', 'newLinkedSet0', 'newLinkedSet2' } + public void testPreferExpectedTypeMembers() { + configureNoCompletion(getTestName(false) + ".java") + myFixture.complete(CompletionType.SMART, 2) + assertPreferredItems 0, 'MyColor.RED', 'Another.RED' + assert lookup.items.size() == 2 + } + @Override protected String getBasePath() { return JavaTestUtil.getRelativeJavaTestDataPath() + BASE_PATH; 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 a45f7a1a540b..6779aacee87d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -774,7 +774,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { } public void testNoClassLiteral() throws Exception { doActionTest(); - assertStringItems("Object.class", "forName", "forName", "getClass"); + assertStringItems("Object.class", "getClass", "forName", "forName"); } public void testClassLiteralInAnno2() throws Throwable {