Keyword completion in method references; cleanup

This commit is contained in:
Roman Shevchenko
2012-06-04 12:19:11 +04:00
parent bd86a3e9bd
commit bf3b222335
5 changed files with 100 additions and 35 deletions
@@ -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<PsiElement, ?> 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<PsiElement, ?> 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;
}
}
@@ -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<PsiElement,?> 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<PsiElement> 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<PsiElement> 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<PsiElement> START_SWITCH = psiElement().afterLeaf(psiElement().withText("{").withParents(PsiCodeBlock.class, PsiSwitchStatement.class));
static final ElementPattern<PsiElement> START_SWITCH =
psiElement().afterLeaf(psiElement().withText("{").withParents(PsiCodeBlock.class, PsiSwitchStatement.class));
private static final ElementPattern<PsiElement> 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<PsiElement> START_FOR =
psiElement().afterLeaf(psiElement().withText("(").afterLeaf("for")).withParents(PsiJavaCodeReferenceElement.class,
PsiExpressionStatement.class, PsiForStatement.class);
private static final PsiJavaElementPattern.Capture<PsiElement> CLASS_REFERENCE =
psiElement().withParent(psiReferenceExpression().referencing(psiClass()));
public static final ElementPattern<PsiElement> 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<LookupElement> {
protected static class OverrideableSpace extends TailTypeDecorator<LookupElement> {
private final TailType myTail;
public OverrideableSpace(LookupElement keyword, TailType tail) {
@@ -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<caret>
}
}
@@ -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;<caret>
}
}
@@ -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");