From bf3b222335792ab306f64da762daee860f841112 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Sun, 3 Jun 2012 13:31:11 +0400 Subject: [PATCH] Keyword completion in method references; cleanup --- .../completion/Java18CompletionData.java | 56 +++++++++++-------- .../completion/JavaCompletionData.java | 32 +++++++---- .../completion/keywords/newInMethodRefs.java | 23 ++++++++ .../keywords/newInMethodRefs_after.java | 23 ++++++++ .../completion/KeywordCompletionTest.java | 1 + 5 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/keywords/newInMethodRefs.java create mode 100644 java/java-tests/testData/codeInsight/completion/keywords/newInMethodRefs_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/Java18CompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/Java18CompletionData.java index d627fc535b0b..a113ec229635 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/Java18CompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/Java18CompletionData.java @@ -15,32 +15,42 @@ */ package com.intellij.codeInsight.completion; -import com.intellij.psi.PsiKeyword; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiParameterList; -import com.intellij.psi.filters.AndFilter; -import com.intellij.psi.filters.ClassFilter; -import com.intellij.psi.filters.ElementFilter; -import com.intellij.psi.filters.TextFilter; -import com.intellij.psi.filters.classes.InterfaceFilter; -import com.intellij.psi.filters.position.LeftNeighbour; -import com.intellij.psi.filters.position.ParentElementFilter; +import com.intellij.codeInsight.TailType; +import com.intellij.patterns.PsiElementPattern; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; + +import static com.intellij.patterns.PsiJavaPatterns.psiClass; +import static com.intellij.patterns.PsiJavaPatterns.psiElement; public class Java18CompletionData extends Java15CompletionData { - @Override - protected void initVariantsInMethodScope() { - super.initVariantsInMethodScope(); + private static final PsiElementPattern AFTER_PARENTH_IN_EXT_METHOD = psiElement() + .afterLeaf(psiElement(JavaTokenType.RPARENTH).withParent(PsiParameterList.class)) + .withSuperParent(3, psiClass().isInterface().nonAnnotationType()); - { - // in extension method - ElementFilter position = new AndFilter( - new LeftNeighbour(new AndFilter( - new TextFilter(")"), - new ParentElementFilter(new ClassFilter(PsiParameterList.class)))), - new ParentElementFilter(new InterfaceFilter(), 3)); - CompletionVariant variant = new CompletionVariant(PsiMethod.class, position); - variant.addCompletion(PsiKeyword.DEFAULT); - registerVariant(variant); + private static final PsiElementPattern AFTER_DOUBLE_COLON = psiElement() + .afterLeaf(psiElement(JavaTokenType.DOUBLE_COLON)); + + @Override + public void fillCompletions(final CompletionParameters parameters, final CompletionResultSet result) { + final PsiElement position = parameters.getPosition(); + + if (!inComment(position)) { + if (AFTER_PARENTH_IN_EXT_METHOD.accepts(position)) { + result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.DEFAULT), TailType.SPACE)); + return; + } + + if (AFTER_DOUBLE_COLON.accepts(position)) { + result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), TailType.SEMICOLON)); + return; + } } + + super.fillCompletions(parameters, result); + } + + private static boolean inComment(final PsiElement position) { + return PsiTreeUtil.getParentOfType(position, PsiComment.class, false) != null; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java index 40ee3e7c8b89..c73f1185b753 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -22,7 +22,9 @@ import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.codeInsight.lookup.TailTypeDecorator; -import com.intellij.patterns.*; +import com.intellij.patterns.ElementPattern; +import com.intellij.patterns.PsiElementPattern; +import com.intellij.patterns.PsiJavaElementPattern; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.filters.*; @@ -44,10 +46,11 @@ import org.jetbrains.annotations.NonNls; import static com.intellij.patterns.PsiJavaPatterns.*; import static com.intellij.patterns.StandardPatterns.not; -public class JavaCompletionData extends JavaAwareCompletionData{ +public class JavaCompletionData extends JavaAwareCompletionData { + private static final @NonNls String[] BLOCK_FINALIZERS = {"{", "}", ";", ":", "else"}; - private static final @NonNls String[] ourBlockFinalizers = {"{", "}", ";", ":", "else"}; private static final PsiElementPattern AFTER_DOT = psiElement().afterLeaf("."); + public static final LeftNeighbour INSTANCEOF_PLACE = new LeftNeighbour(new OrFilter( new ReferenceOnFilter(new ClassFilter(PsiVariable.class)), new TextFilter(PsiKeyword.THIS), @@ -57,16 +60,19 @@ public class JavaCompletionData extends JavaAwareCompletionData{ new ParentElementFilter(new ClassFilter(PsiExpression.class)), new ClassFilter(PsiExpression.class))))), new AndFilter(new TextFilter("]"), new ParentElementFilter(new ClassFilter(PsiArrayAccessExpression.class))))); + public static final PsiJavaElementPattern.Capture VARIABLE_AFTER_FINAL = - PsiJavaPatterns.psiElement().afterLeaf(PsiKeyword.FINAL).inside(PsiDeclarationStatement.class); + psiElement().afterLeaf(PsiKeyword.FINAL).inside(PsiDeclarationStatement.class); + public static final LeftNeighbour AFTER_TRY_BLOCK = new LeftNeighbour(new AndFilter( new TextFilter("}"), new ParentElementFilter(new AndFilter( new LeftNeighbour(new TextFilter(PsiKeyword.TRY)), new ParentElementFilter(new ClassFilter(PsiTryStatement.class))) ))); + public static final PsiJavaElementPattern.Capture INSIDE_PARAMETER_LIST = - PsiJavaPatterns.psiElement().withParent( + psiElement().withParent( psiElement(PsiJavaCodeReferenceElement.class).insideStarting( psiElement().withTreeParent( psiElement(PsiParameterList.class).andNot(psiElement(PsiAnnotationParameterList.class))))); @@ -86,7 +92,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{ new LeftNeighbour( new OrFilter( new AndFilter ( - new TextFilter(ourBlockFinalizers), + new TextFilter(BLOCK_FINALIZERS), new NotFilter ( new SuperParentFilter(new ClassFilter(PsiAnnotation.class)) ) @@ -109,7 +115,8 @@ public class JavaCompletionData extends JavaAwareCompletionData{ START_OF_CODE_FRAGMENT ); - static final ElementPattern START_SWITCH = psiElement().afterLeaf(psiElement().withText("{").withParents(PsiCodeBlock.class, PsiSwitchStatement.class)); + static final ElementPattern START_SWITCH = + psiElement().afterLeaf(psiElement().withText("{").withParents(PsiCodeBlock.class, PsiSwitchStatement.class)); private static final ElementPattern SUPER_OR_THIS_PATTERN = and(JavaSmartCompletionContributor.INSIDE_EXPRESSION, @@ -117,7 +124,6 @@ public class JavaCompletionData extends JavaAwareCompletionData{ not(psiElement().afterLeaf(psiElement().withText(".").afterLeaf(PsiKeyword.THIS, PsiKeyword.SUPER))), not(START_SWITCH)); - public static final AndFilter CLASS_START = new AndFilter( new OrFilter( END_OF_BLOCK, @@ -135,14 +141,16 @@ public class JavaCompletionData extends JavaAwareCompletionData{ PsiKeyword.CHAR, PsiKeyword.BYTE }; - final static ElementFilter CLASS_BODY = new OrFilter( + private static final ElementFilter CLASS_BODY = new OrFilter( new AfterElementFilter(new TextFilter("{")), new ScopeFilter(new ClassFilter(JspClassLevelDeclarationStatement.class))); + public static final ElementPattern START_FOR = psiElement().afterLeaf(psiElement().withText("(").afterLeaf("for")).withParents(PsiJavaCodeReferenceElement.class, PsiExpressionStatement.class, PsiForStatement.class); private static final PsiJavaElementPattern.Capture CLASS_REFERENCE = psiElement().withParent(psiReferenceExpression().referencing(psiClass())); + public static final ElementPattern EXPR_KEYWORDS = and( psiElement().withParent(psiElement(PsiReferenceExpression.class).withParent( not( @@ -312,7 +320,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{ } } - protected void initVariantsInMethodScope() { + private void initVariantsInMethodScope() { // Completion for classes in method throws section // position { @@ -653,7 +661,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{ return false; } - private static LookupElement createKeyword(PsiElement position, String keyword) { + protected static LookupElement createKeyword(PsiElement position, String keyword) { return BasicExpressionCompletionContributor.createKeywordLookupItem(position, keyword); } @@ -694,7 +702,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{ return false; } - private static class OverrideableSpace extends TailTypeDecorator { + protected static class OverrideableSpace extends TailTypeDecorator { private final TailType myTail; public OverrideableSpace(LookupElement keyword, TailType tail) { diff --git a/java/java-tests/testData/codeInsight/completion/keywords/newInMethodRefs.java b/java/java-tests/testData/codeInsight/completion/keywords/newInMethodRefs.java new file mode 100644 index 000000000000..1f42d81b2a69 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/keywords/newInMethodRefs.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Foo { + interface I { Object m(); } + + void test() { + I i = Foo::n + } +} diff --git a/java/java-tests/testData/codeInsight/completion/keywords/newInMethodRefs_after.java b/java/java-tests/testData/codeInsight/completion/keywords/newInMethodRefs_after.java new file mode 100644 index 000000000000..dfc740a4ea3d --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/keywords/newInMethodRefs_after.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Foo { + interface I { Object m(); } + + void test() { + I i = Foo::new; + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java index a8d77fc098e2..7e407253dab0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java @@ -89,6 +89,7 @@ public class KeywordCompletionTest extends LightCompletionTestCase { public void testDefaultInExtMethod() throws Exception { doTest(false); } public void testNullInMethodCall() throws Exception { doTest(false); } public void testNullInMethodCall2() throws Exception { doTest(false); } + public void testNewInMethodRefs() throws Exception { doTest(false); } public void testTryInExpression() throws Exception { configureByFile(BASE_PATH + "/" + getTestName(true) + ".java");