diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java index 661e7862ef3f..3c06289dd6ea 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java @@ -34,6 +34,7 @@ import static com.intellij.psi.SyntaxTraverser.psiApi; public class JavaKeywordCompletion { public static final ElementPattern AFTER_DOT = psiElement().afterLeaf("."); + private static final ElementPattern AFTER_DOUBLE_COLON = psiElement().afterLeaf("::"); static final ElementPattern VARIABLE_AFTER_FINAL = psiElement().afterLeaf(PsiKeyword.FINAL).inside(PsiDeclarationStatement.class); @@ -417,10 +418,12 @@ public class JavaKeywordCompletion { } private void addExpressionKeywords(boolean statementPosition) { - if (psiElement(JavaTokenType.DOUBLE_COLON).accepts(myPrevLeaf)) { + if (AFTER_DOUBLE_COLON.accepts(myPosition)) { PsiMethodReferenceExpression parent = PsiTreeUtil.getParentOfType(myPosition, PsiMethodReferenceExpression.class); - TailType tail = parent != null && !LambdaHighlightingUtil.insertSemicolon(parent.getParent()) ? TailType.SEMICOLON : TailType.NONE; - addKeyword(new OverridableSpace(createKeyword(PsiKeyword.NEW), tail)); + if (parent != null && canUseConstructorReference(parent)) { + TailType tail = !LambdaHighlightingUtil.insertSemicolon(parent.getParent()) ? TailType.SEMICOLON : TailType.NONE; + addKeyword(new OverridableSpace(createKeyword(PsiKeyword.NEW), tail)); + } return; } @@ -442,6 +445,17 @@ public class JavaKeywordCompletion { } } + private static boolean canUseConstructorReference(PsiMethodReferenceExpression ref) { + PsiTypeElement qualifierType = ref.getQualifierType(); + if (qualifierType == null) { + PsiElement qualifier = ref.getQualifier(); + return qualifier instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement)qualifier).resolve() != null; + } + + if (qualifierType instanceof PsiClassType) return ((PsiClassType)qualifierType).resolve() != null; + return qualifierType instanceof PsiArrayType; + } + private boolean isQualifiedNewContext() { if (myPosition.getParent() instanceof PsiReferenceExpression) { PsiExpression qualifier = ((PsiReferenceExpression)myPosition.getParent()).getQualifierExpression(); @@ -644,6 +658,7 @@ public class JavaKeywordCompletion { static void addPrimitiveTypes(Consumer result, PsiElement position, JavaCompletionSession session) { if (AFTER_DOT.accepts(position) || + AFTER_DOUBLE_COLON.accepts(position) || psiElement().inside(psiAnnotation()).accepts(position) && !expectsClassLiteral(position)) { return; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/ChainedMethodReferenceWithNoPrefix.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/ChainedMethodReferenceWithNoPrefix.java new file mode 100644 index 000000000000..3674e23e2c72 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/ChainedMethodReferenceWithNoPrefix.java @@ -0,0 +1,5 @@ +class A { + { + Runnable r = Strings:: + } +} 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 273be4cd959e..a9b9b17556b5 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 @@ -340,6 +340,13 @@ class Test88 { checkResultByFileName() } + void testChainedMethodReferenceWithNoPrefix() { + myFixture.addClass("package bar; public class Strings {}") + myFixture.addClass("package foo; public class Strings { public static void goo() {} }") + configureByTestName() + myFixture.assertPreferredCompletionItems 0, 'Strings::goo' + } + void testPreferVariableToLambda() { configureByTestName() myFixture.assertPreferredCompletionItems 0, 'output', 'out -> '