mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
completion: place functional expressions after variables of expected type (IDEA-174428, IDEA-178600)
This commit is contained in:
+8
-3
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
@@ -53,6 +54,7 @@ public class FunctionalExpressionCompletionProvider extends CompletionProvider<C
|
||||
JavaCompletionUtil.insertClassReference(psiClass, context.getFile(), start, start + insertedName.length());
|
||||
}
|
||||
};
|
||||
static final Key<Boolean> FUNCTIONAL_EXPR_ITEM = Key.create("FUNCTIONAL_EXPR_ITEM");
|
||||
|
||||
private static boolean isLambdaContext(@NotNull PsiElement element) {
|
||||
final PsiElement rulezzRef = element.getParent();
|
||||
@@ -105,13 +107,16 @@ public class FunctionalExpressionCompletionProvider extends CompletionProvider<C
|
||||
.withPresentableText(paramsString + " -> {}")
|
||||
.withTypeText(functionalInterfaceType.getPresentableText())
|
||||
.withIcon(AllIcons.Nodes.Function);
|
||||
LookupElement lambdaElement = builder.withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
result.consume(smart ? lambdaElement : PrioritizedLookupElement.withPriority(lambdaElement, 1));
|
||||
builder.putUserData(FUNCTIONAL_EXPR_ITEM, true);
|
||||
result.consume(builder.withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE));
|
||||
}
|
||||
|
||||
addMethodReferenceVariants(
|
||||
smart, addInheritors, parameters, matcher, functionalInterfaceType, functionalInterfaceMethod, params, originalPosition, substitutor,
|
||||
element -> result.consume(smart ? JavaSmartCompletionContributor.decorate(element, Arrays.asList(expectedTypes)) : element));
|
||||
element -> {
|
||||
element.putUserData(FUNCTIONAL_EXPR_ITEM, true);
|
||||
result.consume(smart ? JavaSmartCompletionContributor.decorate(element, Arrays.asList(expectedTypes)) : element);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementWeigher;
|
||||
import com.intellij.codeInsight.lookup.TypedLookupItem;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.openapi.util.Key;
|
||||
@@ -133,6 +134,8 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
annoMethod,
|
||||
probableKeyword,
|
||||
castVariable,
|
||||
expectedTypeVariable,
|
||||
funExpr,
|
||||
variable,
|
||||
getter,
|
||||
qualifiedWithField,
|
||||
@@ -171,13 +174,17 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
if (object instanceof PsiLocalVariable || object instanceof PsiParameter ||
|
||||
object instanceof PsiThisExpression ||
|
||||
object instanceof PsiField && !((PsiField)object).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return MyResult.variable;
|
||||
return isExpectedTypeItem(item) ? MyResult.expectedTypeVariable : MyResult.variable;
|
||||
}
|
||||
|
||||
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
|
||||
return MyResult.superMethodParameters;
|
||||
}
|
||||
|
||||
if (item.getUserData(FunctionalExpressionCompletionProvider.FUNCTIONAL_EXPR_ITEM) != null) {
|
||||
return MyResult.funExpr;
|
||||
}
|
||||
|
||||
if (object instanceof PsiMethod) {
|
||||
PsiClass containingClass = ((PsiMethod)object).getContainingClass();
|
||||
if (containingClass != null && CommonClassNames.JAVA_UTIL_COLLECTIONS.equals(containingClass.getQualifiedName())) {
|
||||
@@ -248,6 +255,12 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
private boolean isExpectedTypeItem(@NotNull LookupElement item) {
|
||||
TypedLookupItem typed = item.as(TypedLookupItem.CLASS_CONDITION_KEY);
|
||||
PsiType itemType = typed == null ? null : typed.getType();
|
||||
return itemType != null && Arrays.stream(myExpectedTypes).anyMatch(info -> info.getType().isAssignableFrom(itemType));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ThreeState isProbableKeyword(String keyword) {
|
||||
if (PsiKeyword.RETURN.equals(keyword)) {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Foo {
|
||||
void processImports(java.util.function.Predicate<String> pr) {}
|
||||
|
||||
{
|
||||
processImports(<caret>);
|
||||
}
|
||||
|
||||
static <T> T getSomeGenericValue(T t) {}
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
interface I {
|
||||
void foo(String out);
|
||||
}
|
||||
|
||||
class Foo {
|
||||
I output;
|
||||
|
||||
{
|
||||
I r = out<caret>
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -106,8 +106,8 @@ class Test {
|
||||
void bar(int i) {}
|
||||
}"""
|
||||
def items = myFixture.completeBasic()
|
||||
assert LookupElementPresentation.renderElement(items[0]).itemText == 'x -> {}'
|
||||
assert items.find { LookupElementPresentation.renderElement(it).itemText.contains('this::bar') } != null
|
||||
assert items.any { LookupElementPresentation.renderElement(it).itemText == 'x -> {}' }
|
||||
assert items.any { LookupElementPresentation.renderElement(it).itemText.contains('this::bar') }
|
||||
}
|
||||
|
||||
void "test suggest receiver method reference"() {
|
||||
@@ -301,6 +301,11 @@ class Test88 {
|
||||
checkResultByFileName()
|
||||
}
|
||||
|
||||
void testPreferVariableToLambda() {
|
||||
configureByTestName()
|
||||
myFixture.assertPreferredCompletionItems 0, 'output', 'out -> '
|
||||
}
|
||||
|
||||
private checkResultByFileName() {
|
||||
checkResultByFile(getTestName(false) + "_after.java")
|
||||
}
|
||||
|
||||
+4
@@ -258,4 +258,8 @@ public void testConvertToObjectStream() {
|
||||
public void testNewHashMapTypeArguments() { doTest(false); }
|
||||
public void testNewMapTypeArguments() { doTest(false); }
|
||||
|
||||
public void testPreferLambdaOverGenericGetter() {
|
||||
configureByTestName();
|
||||
myFixture.assertPreferredCompletionItems(0, "isEmpty", "s -> ", "getSomeGenericValue");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user