mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
static method reference completion (IDEA-124043)
This commit is contained in:
@@ -804,7 +804,7 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean insertTail(InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) {
|
||||
public static boolean insertTail(InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) {
|
||||
TailType toInsert = tailType;
|
||||
LookupItem<?> lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY);
|
||||
if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) {
|
||||
|
||||
-2
@@ -108,8 +108,6 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
public boolean accepts(@NotNull PsiElement element, ProcessingContext context) {
|
||||
final PsiElement rulezzRef = element.getParent();
|
||||
return rulezzRef != null &&
|
||||
rulezzRef instanceof PsiMethodReferenceExpression &&
|
||||
((PsiReferenceExpression)rulezzRef).getQualifier() != element &&
|
||||
LambdaUtil.isValidLambdaContext(rulezzRef.getParent());
|
||||
}});
|
||||
|
||||
|
||||
+64
-7
@@ -17,9 +17,12 @@ package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfoImpl;
|
||||
import com.intellij.codeInsight.PsiEquivalenceUtil;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -44,7 +47,8 @@ public class MethodReferenceCompletionProvider extends CompletionProvider<Comple
|
||||
final PsiType functionalType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(defaultType);
|
||||
final PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalType);
|
||||
if (returnType != null) {
|
||||
final PsiMethodReferenceExpression ref = (PsiMethodReferenceExpression)parameters.getPosition().getParent();
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiElement refPlace = position.getParent();
|
||||
final ExpectedTypeInfoImpl typeInfo =
|
||||
new ExpectedTypeInfoImpl(returnType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, returnType, TailType.UNKNOWN, null,
|
||||
ExpectedTypeInfoImpl.NULL);
|
||||
@@ -54,15 +58,17 @@ public class MethodReferenceCompletionProvider extends CompletionProvider<Comple
|
||||
public void consume(final LookupElement lookupElement) {
|
||||
final PsiElement element = lookupElement.getPsiElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
final PsiMethodReferenceExpression referenceExpression = (PsiMethodReferenceExpression)ref.copy();
|
||||
final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement();
|
||||
LOG.assertTrue(referenceNameElement != null, referenceExpression);
|
||||
referenceNameElement.replace(JavaPsiFacade.getElementFactory(element.getProject()).createIdentifier(((PsiMethod)element).getName()));
|
||||
final PsiMethodReferenceExpression referenceExpression = createMethodReferenceExpression((PsiMethod)element);
|
||||
if (referenceExpression == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiType added = map.put(referenceExpression, functionalType);
|
||||
try {
|
||||
final PsiElement resolve = referenceExpression.resolve();
|
||||
if (resolve == element && PsiMethodReferenceUtil.checkMethodReferenceContext(referenceExpression, resolve, functionalType) == null) {
|
||||
result.addElement(lookupElement);
|
||||
if (resolve != null && PsiEquivalenceUtil.areElementsEquivalent(element, resolve) &&
|
||||
PsiMethodReferenceUtil.checkMethodReferenceContext(referenceExpression, resolve, functionalType) == null) {
|
||||
result.addElement(new JavaMethodReferenceElement((PsiMethod)element, refPlace, referenceExpression));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -72,6 +78,26 @@ public class MethodReferenceCompletionProvider extends CompletionProvider<Comple
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PsiMethodReferenceExpression createMethodReferenceExpression(PsiMethod method) {
|
||||
if (refPlace instanceof PsiMethodReferenceExpression) {
|
||||
final PsiMethodReferenceExpression referenceExpression = (PsiMethodReferenceExpression)refPlace.copy();
|
||||
final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement();
|
||||
LOG.assertTrue(referenceNameElement != null, referenceExpression);
|
||||
referenceNameElement.replace(JavaPsiFacade.getElementFactory(method.getProject()).createIdentifier(method.getName()));
|
||||
return referenceExpression;
|
||||
}
|
||||
else if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass aClass = method.getContainingClass();
|
||||
LOG.assertTrue(aClass != null);
|
||||
final String qualifiedName = aClass.getQualifiedName();
|
||||
return (PsiMethodReferenceExpression)JavaPsiFacade.getElementFactory(method.getProject()).createExpressionFromText(
|
||||
qualifiedName + "::" + method.getName(), refPlace);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final Runnable runnable = ReferenceExpressionCompletionContributor
|
||||
@@ -83,4 +109,35 @@ public class MethodReferenceCompletionProvider extends CompletionProvider<Comple
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class JavaMethodReferenceElement extends JavaMethodCallElement {
|
||||
private final PsiMethod myMethod;
|
||||
private final PsiElement myRefPlace;
|
||||
private PsiMethodReferenceExpression myReferenceExpression;
|
||||
|
||||
public JavaMethodReferenceElement(PsiMethod method, PsiElement refPlace, PsiMethodReferenceExpression referenceExpression) {
|
||||
super(method);
|
||||
myMethod = method;
|
||||
myRefPlace = refPlace;
|
||||
myReferenceExpression = referenceExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
if (!(myRefPlace instanceof PsiMethodReferenceExpression)) {
|
||||
final PsiClass containingClass = myMethod.getContainingClass();
|
||||
LOG.assertTrue(containingClass != null);
|
||||
final String qualifiedName = containingClass.getQualifiedName();
|
||||
LOG.assertTrue(qualifiedName != null);
|
||||
|
||||
final Editor editor = context.getEditor();
|
||||
final Document document = editor.getDocument();
|
||||
final int startOffset = context.getStartOffset();
|
||||
|
||||
document.insertString(startOffset, qualifiedName + "::");
|
||||
JavaCompletionUtil.shortenReference(context.getFile(), startOffset + qualifiedName.length() - 1);
|
||||
JavaCompletionUtil.insertTail(context, this, handleCompletionChar(context.getEditor(), this, context.getCompletionChar()), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.ArrayList;
|
||||
|
||||
class B {
|
||||
static void bar(String s){}
|
||||
{
|
||||
new ArrayList<String>().forEach(B::bar);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.ArrayList;
|
||||
|
||||
class B {
|
||||
static void bar(String s){}
|
||||
{
|
||||
new ArrayList<String>().forEach(<caret>);
|
||||
}
|
||||
}
|
||||
+4
@@ -93,6 +93,10 @@ public class SmartType18CompletionTest extends LightFixtureCompletionTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testNoQualifier() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testFilterAmbiguity() throws Exception {
|
||||
configureByFile("/" + getTestName(false) + ".java");
|
||||
assertNotNull(myItems);
|
||||
|
||||
Reference in New Issue
Block a user