don't show explicit method type parameters in lookups when they won't be inserted

This commit is contained in:
peter
2011-11-10 17:16:30 +01:00
parent 87349eeab9
commit 9ba73d70b6
9 changed files with 72 additions and 35 deletions
@@ -48,37 +48,37 @@ class CollectionsUtilityMethodsProvider {
if (parameters.getParameters().getInvocationCount() > 1 ||
pparent instanceof PsiReturnStatement ||
pparent instanceof PsiConditionalExpression && pparent.getParent() instanceof PsiReturnStatement) {
addCollectionMethod(result, type, defaultType, JAVA_UTIL_LIST, "emptyList", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_SET, "emptySet", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_MAP, "emptyMap", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_LIST, "emptyList", collectionsClass, element);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_SET, "emptySet", collectionsClass, element);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_MAP, "emptyMap", collectionsClass, element);
}
if (parameters.getParameters().getInvocationCount() > 1) {
addCollectionMethod(result, type, defaultType, JAVA_UTIL_LIST, "singletonList", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_SET, "singleton", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_MAP, "singletonMap", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_LIST, "singletonList", collectionsClass, element);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_SET, "singleton", collectionsClass, element);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_MAP, "singletonMap", collectionsClass, element);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_COLLECTION, "unmodifiableCollection", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_LIST, "unmodifiableList", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_SET, "unmodifiableSet", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_MAP, "unmodifiableMap", collectionsClass);
addCollectionMethod(result, type, defaultType, "java.util.SortedSet", "unmodifiableSortedSet", collectionsClass);
addCollectionMethod(result, type, defaultType, "java.util.SortedMap", "unmodifiableSortedMap", collectionsClass);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_COLLECTION, "unmodifiableCollection", collectionsClass, element);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_LIST, "unmodifiableList", collectionsClass, element);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_SET, "unmodifiableSet", collectionsClass, element);
addCollectionMethod(result, type, defaultType, JAVA_UTIL_MAP, "unmodifiableMap", collectionsClass, element);
addCollectionMethod(result, type, defaultType, "java.util.SortedSet", "unmodifiableSortedSet", collectionsClass, element);
addCollectionMethod(result, type, defaultType, "java.util.SortedMap", "unmodifiableSortedMap", collectionsClass, element);
}
}
private static void addCollectionMethod(final Consumer<LookupElement> result, final PsiType expectedType,
final PsiType defaultType, final String baseClassName,
@NonNls final String method, @NotNull final PsiClass collectionsClass) {
@NonNls final String method, @NotNull final PsiClass collectionsClass, PsiElement place) {
if (isClassType(expectedType, baseClassName) || isClassType(expectedType, JAVA_UTIL_COLLECTION)) {
addMethodItem(result, expectedType, method, collectionsClass);
addMethodItem(result, expectedType, method, collectionsClass, place);
} else if (isClassType(defaultType, baseClassName) || isClassType(defaultType, JAVA_UTIL_COLLECTION)) {
addMethodItem(result, defaultType, method, collectionsClass);
addMethodItem(result, defaultType, method, collectionsClass, place);
}
}
private static void addMethodItem(Consumer<LookupElement> result, PsiType expectedType, String methodName, PsiClass containingClass) {
private static void addMethodItem(Consumer<LookupElement> result, PsiType expectedType, String methodName, PsiClass containingClass, PsiElement place) {
final PsiMethod[] methods = containingClass.findMethodsByName(methodName, false);
if (methods.length == 0) {
return;
@@ -87,7 +87,7 @@ class CollectionsUtilityMethodsProvider {
final PsiMethod method = methods[0];
final JavaMethodCallElement item = new JavaMethodCallElement(method, false, false);
item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType));
item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType), place);
item.putUserData(COLLECTION_FACTORY, true);
result.consume(item);
}
@@ -528,7 +528,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() > 1, new Consumer<LookupElement>() {
new JavaMembersGetter(info.getDefaultType(), position).addMembers(position, parameters.getInvocationCount() > 1, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
result.addElement(element);
@@ -21,7 +21,6 @@ import com.intellij.codeInsight.lookup.impl.JavaElementLookupRenderer;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.ClassConditionKey;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -33,10 +32,11 @@ import org.jetbrains.annotations.Nullable;
*/
public class JavaMethodCallElement extends LookupItem<PsiMethod> implements TypedLookupItem, StaticallyImportable {
public static final ClassConditionKey<JavaMethodCallElement> CLASS_CONDITION_KEY = ClassConditionKey.create(JavaMethodCallElement.class);
private static final Key<PsiSubstitutor> INFERENCE_SUBSTITUTOR = Key.create("INFERENCE_SUBSTITUTOR");
@Nullable private final PsiClass myContainingClass;
private final PsiMethod myMethod;
private final MemberLookupHelper myHelper;
private PsiSubstitutor myInferenceSubstitutor = PsiSubstitutor.EMPTY;
private boolean myMayNeedExplicitTypeParameters;
public JavaMethodCallElement(@NotNull PsiMethod method) {
super(method, method.getName());
@@ -59,8 +59,9 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
return getSubstitutor().substitute(getInferenceSubstitutor().substitute(getObject().getReturnType()));
}
public void setInferenceSubstitutor(@NotNull final PsiSubstitutor substitutor) {
setAttribute(INFERENCE_SUBSTITUTOR, substitutor);
public void setInferenceSubstitutor(@NotNull final PsiSubstitutor substitutor, PsiElement place) {
myInferenceSubstitutor = substitutor;
myMayNeedExplicitTypeParameters = mayNeedTypeParameters(place);
}
@NotNull
@@ -71,8 +72,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
@NotNull
public PsiSubstitutor getInferenceSubstitutor() {
final PsiSubstitutor substitutor = getAttribute(INFERENCE_SUBSTITUTOR);
return substitutor == null ? PsiSubstitutor.EMPTY : substitutor;
return myInferenceSubstitutor;
}
@Override
@@ -90,6 +90,22 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
return canBeImported() && myHelper.willBeImported();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof JavaMethodCallElement)) return false;
if (!super.equals(o)) return false;
return myInferenceSubstitutor.equals(((JavaMethodCallElement)o).myInferenceSubstitutor);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myInferenceSubstitutor.hashCode();
return result;
}
@Override
public void handleInsert(InsertionContext context) {
final Document document = context.getDocument();
@@ -103,7 +119,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
final int startOffset = context.getStartOffset();
final OffsetKey refStart = context.trackOffset(startOffset, true);
if (mayNeedTypeParameters(context) && shouldInsertTypeParameters()) {
if (shouldInsertTypeParameters() && mayNeedTypeParameters(context.getFile().findElementAt(context.getStartOffset()))) {
qualifyMethodCall(file, startOffset, document);
insertExplicitTypeParameters(context, refStart);
}
@@ -135,11 +151,10 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
}
private boolean shouldInsertTypeParameters() {
return !getInferenceSubstitutor().equals(PsiSubstitutor.EMPTY) && myMethod.getParameterList().getParametersCount() == 0;
return myMayNeedExplicitTypeParameters && !getInferenceSubstitutor().equals(PsiSubstitutor.EMPTY) && myMethod.getParameterList().getParametersCount() == 0;
}
private static boolean mayNeedTypeParameters(InsertionContext context) {
final PsiElement leaf = context.getFile().findElementAt(context.getStartOffset());
public static boolean mayNeedTypeParameters(final PsiElement leaf) {
if (PsiTreeUtil.getParentOfType(leaf, PsiExpressionList.class, true, PsiCodeBlock.class, PsiModifierListOwner.class) == null) {
if (PsiTreeUtil.getParentOfType(leaf, PsiConditionalExpression.class, true, PsiCodeBlock.class, PsiModifierListOwner.class) == null) {
return false;
@@ -239,6 +254,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
}
String itemText = presentation.getItemText();
assert itemText != null;
int i = itemText.indexOf('.');
if (i > 0) {
presentation.setItemText(itemText.substring(0, i + 1) + typeParamsText + itemText.substring(i + 1));
@@ -224,9 +224,9 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
!(parent.getParent() instanceof PsiSwitchLabelStatement)) {
for (ExpectedTypeInfo info : mergedInfos) {
final boolean searchInheritors = params.getInvocationCount() > 1;
new JavaMembersGetter(info.getType()).addMembers(position, searchInheritors, noTypeCheck);
new JavaMembersGetter(info.getType(), position).addMembers(position, searchInheritors, noTypeCheck);
if (!info.getDefaultType().equals(info.getType())) {
new JavaMembersGetter(info.getDefaultType()).addMembers(position, searchInheritors, noTypeCheck);
new JavaMembersGetter(info.getDefaultType(), position).addMembers(position, searchInheritors, noTypeCheck);
}
}
}
@@ -172,7 +172,7 @@ public class ReferenceExpressionCompletionContributor {
assert item != null;
final PsiMethod method = (PsiMethod)lookupElement.getObject();
if (SmartCompletionDecorator.hasUnboundTypeParams(method, parameters.getExpectedType())) {
item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, parameters.getExpectedType()));
item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, parameters.getExpectedType()), element);
}
}
}
@@ -33,8 +33,10 @@ import org.jetbrains.annotations.Nullable;
*/
public class JavaMembersGetter extends MembersGetter {
private final PsiType myExpectedType;
private final PsiElement myPlace;
public JavaMembersGetter(@NotNull PsiType expectedType) {
public JavaMembersGetter(@NotNull PsiType expectedType, PsiElement place) {
myPlace = place;
myExpectedType = JavaCompletionUtil.originalize(expectedType);
}
@@ -120,7 +122,7 @@ public class JavaMembersGetter extends MembersGetter {
JavaMethodCallElement item = new JavaMethodCallElement(method, false, false);
item.setInferenceSubstitutor(substitutor);
item.setInferenceSubstitutor(substitutor, myPlace);
return item;
}
}
@@ -2,7 +2,11 @@ import java.util.Map;
public class Foo {
Set<String> bar() {
Map<String, String> s = em<caret>
void foo(Map<String, String> map) {
}
void bar() {
foo(em<caret>)
}
}
@@ -0,0 +1,8 @@
import java.util.Map;
public class Foo {
Set<String> bar() {
Map<String, String> s = em<caret>
}
}
@@ -197,6 +197,13 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase {
assertEquals("Collections.<String, S...>emptyMap", presentation.getItemText());
}
public void testEmptyMapPresentation2() {
configure();
LookupElementPresentation presentation = new LookupElementPresentation();
myItems[0].renderElement(presentation);
assertEquals("Collections.emptyMap", presentation.getItemText());
}
@Override
protected void complete() {
complete(2);