From 03a663c63e18f9e57796342c35f4d27949d4c559 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 5 Jun 2017 16:12:41 +0200 Subject: [PATCH] IDEA-165006 Support chained completion for method references in Java 8+ --- .../completion/JavaChainLookupElement.java | 17 ++++++----- .../completion/JavaNoVariantsDelegator.java | 9 +++--- ...erenceExpressionCompletionContributor.java | 11 ++++++-- .../normal/ChainedMethodReference.java | 5 ++++ .../normal/ChainedMethodReference_after.java | 5 ++++ .../completion/Normal8CompletionTest.groovy | 28 ++++++++++++------- 6 files changed, 51 insertions(+), 24 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/ChainedMethodReference.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/ChainedMethodReference_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java index 7f3f8a33b0af..40a9d3b70af7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java @@ -19,7 +19,6 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementDecorator; import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.codeInsight.lookup.TypedLookupItem; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.ClassConditionKey; import com.intellij.openapi.util.Key; @@ -39,19 +38,23 @@ import java.util.Set; */ public class JavaChainLookupElement extends LookupElementDecorator implements TypedLookupItem { public static final Key CHAIN_QUALIFIER = Key.create("CHAIN_QUALIFIER"); - private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.JavaChainLookupElement"); public static final ClassConditionKey CLASS_CONDITION_KEY = ClassConditionKey.create(JavaChainLookupElement.class); private final LookupElement myQualifier; + private final String mySeparator; public JavaChainLookupElement(LookupElement qualifier, LookupElement main) { + this(qualifier, main, "."); + } + public JavaChainLookupElement(LookupElement qualifier, LookupElement main, String separator) { super(main); myQualifier = qualifier; + mySeparator = separator; } @NotNull @Override public String getLookupString() { - return maybeAddParentheses(myQualifier.getLookupString()) + "." + getDelegate().getLookupString(); + return maybeAddParentheses(myQualifier.getLookupString()) + mySeparator + getDelegate().getLookupString(); } public LookupElement getQualifier() { @@ -70,7 +73,7 @@ public class JavaChainLookupElement extends LookupElementDecorator + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/ChainedMethodReference_after.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/ChainedMethodReference_after.java new file mode 100644 index 000000000000..eb1f75bd4b66 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/ChainedMethodReference_after.java @@ -0,0 +1,5 @@ +class A { + { + Runnable r = System::setOut; + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy index 30a1fbd37628..ae0af6127049 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy @@ -212,37 +212,37 @@ class Test88 { void testCollectorsToList() { configureByTestName() selectItem(myItems.find { it.lookupString.contains('toList') }) - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testStaticallyImportedCollectorsToList() { configureByTestName() selectItem(myItems.find { it.lookupString.contains('collect(toList())') }) - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testAllCollectors() { configureByTestName() myFixture.assertPreferredCompletionItems 0, 'collect', 'collect', 'collect(Collectors.toCollection())', 'collect(Collectors.toList())', 'collect(Collectors.toSet())' selectItem(myItems.find { it.lookupString.contains('toCollection') }) - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testCollectorsToSet() { configureByTestName() selectItem(myItems.find { it.lookupString.contains('toSet') }) - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testNoExplicitTypeArgsInTernary() { configureByTestName() selectItem(myItems.find { it.lookupString.contains('empty') }) - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testCallBeforeLambda() { configureByTestName() - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testLambdaInAmbiguousCall() { @@ -264,13 +264,13 @@ class Test88 { void testNoSemicolonAfterVoidMethodInLambda() { configureByTestName() myFixture.type('l\t') - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testFinishMethodReferenceWithColon() { configureByTestName() myFixture.type(':') - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testPreferLocalsOverMethodRefs() { @@ -286,14 +286,22 @@ class Test88 { "}") configureByTestName() myFixture.type('\n') - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } void testOverrideMethodAsDefault() { configureByTestName() assert LookupElementPresentation.renderElement(myFixture.lookupElements[0]).itemText == 'default void run' myFixture.type('\t') - checkResultByFile(getTestName(false) + "_after.java") + checkResultByFileName() } + void testChainedMethodReference() { + configureByTestName() + checkResultByFileName() + } + + private checkResultByFileName() { + checkResultByFile(getTestName(false) + "_after.java") + } } \ No newline at end of file