mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Keyword completion for new extension method syntax
This commit is contained in:
@@ -20,32 +20,33 @@ 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 {
|
||||
private static final PsiElementPattern<PsiElement, ?> AFTER_PARENTH_IN_EXT_METHOD = psiElement()
|
||||
.afterLeaf(psiElement(JavaTokenType.RPARENTH).withParent(PsiParameterList.class))
|
||||
.withSuperParent(3, psiClass().isInterface().nonAnnotationType());
|
||||
|
||||
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();
|
||||
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));
|
||||
if (AFTER_DOUBLE_COLON.accepts(position)) {
|
||||
PsiMethodReferenceExpression parent = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiMethodReferenceExpression.class);
|
||||
TailType tail = parent != null && !LambdaHighlightingUtil.insertSemicolon(parent.getParent()) ? TailType.SEMICOLON : TailType.NONE;
|
||||
result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), tail));
|
||||
return;
|
||||
}
|
||||
|
||||
if (AFTER_DOUBLE_COLON.accepts(position)) {
|
||||
final PsiMethodReferenceExpression parent = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiMethodReferenceExpression.class);
|
||||
final TailType tailType = parent != null && !LambdaHighlightingUtil.insertSemicolon(parent.getParent()) ? TailType.SEMICOLON : TailType.NONE;
|
||||
result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), tailType));
|
||||
return;
|
||||
if (isSuitableForClass(position)) {
|
||||
PsiElement scope = position.getParent();
|
||||
while (scope != null && !(scope instanceof PsiFile)) {
|
||||
if (scope instanceof PsiClass && ((PsiClass)scope).isInterface()) {
|
||||
result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.DEFAULT), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
break;
|
||||
}
|
||||
scope = scope.getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -29,15 +29,29 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: ik
|
||||
* Date: 17.02.2003
|
||||
* Time: 17:03:09
|
||||
* To change this template use Options | File Templates.
|
||||
* @author ik
|
||||
* @since 17.02.2003
|
||||
*/
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public class ModifierChooser {
|
||||
private static final String[][] CLASS_MODIFIERS = {
|
||||
{PsiKeyword.PUBLIC},
|
||||
{PsiKeyword.FINAL, PsiKeyword.ABSTRACT}
|
||||
};
|
||||
private static final String[][] CLASS_MEMBER_MODIFIERS = {
|
||||
{PsiKeyword.PUBLIC, PsiKeyword.PROTECTED, PsiKeyword.PRIVATE},
|
||||
{PsiKeyword.STATIC},
|
||||
{PsiKeyword.FINAL, PsiKeyword.ABSTRACT},
|
||||
{PsiKeyword.NATIVE},
|
||||
{PsiKeyword.SYNCHRONIZED},
|
||||
{PsiKeyword.STRICTFP},
|
||||
{PsiKeyword.VOLATILE},
|
||||
{PsiKeyword.TRANSIENT}
|
||||
};
|
||||
private static final String[][] INTERFACE_MEMBER_MODIFIERS = {
|
||||
{PsiKeyword.PUBLIC, PsiKeyword.PROTECTED},
|
||||
{PsiKeyword.STATIC},
|
||||
{PsiKeyword.FINAL, PsiKeyword.ABSTRACT}
|
||||
};
|
||||
|
||||
static String[] getKeywords(@NotNull PsiElement position) {
|
||||
final PsiModifierList list = findModifierList(position);
|
||||
@@ -61,27 +75,11 @@ public class ModifierChooser {
|
||||
}
|
||||
|
||||
public static String[] addClassModifiers(PsiModifierList list) {
|
||||
return addKeywords(list, new String[][]{
|
||||
new String[]{"public"},
|
||||
new String[]{"final", "abstract"}
|
||||
});
|
||||
return addKeywords(list, CLASS_MODIFIERS);
|
||||
}
|
||||
|
||||
public static String[] addMemberModifiers(PsiModifierList list, final boolean inInterface) {
|
||||
return addKeywords(list, inInterface ? new String[][]{
|
||||
new String[]{"public", "protected"},
|
||||
new String[]{"static"},
|
||||
new String[]{"final", "abstract"}
|
||||
} : new String[][]{
|
||||
new String[]{"public", "protected", "private"},
|
||||
new String[]{"static"},
|
||||
new String[]{"final", "abstract"},
|
||||
new String[]{"native"},
|
||||
new String[]{"synchronized"},
|
||||
new String[]{"strictfp"},
|
||||
new String[]{"volatile"},
|
||||
new String[]{"transient"}
|
||||
});
|
||||
return addKeywords(list, inInterface ? INTERFACE_MEMBER_MODIFIERS : CLASS_MEMBER_MODIFIERS);
|
||||
}
|
||||
|
||||
private static String[] addKeywords(PsiModifierList list, String[][] keywordSets) {
|
||||
@@ -90,7 +88,7 @@ public class ModifierChooser {
|
||||
final String[] keywords = keywordSets[keywordSets.length - i - 1];
|
||||
boolean containModifierFlag = false;
|
||||
if (list != null) {
|
||||
for (String keyword : keywords) {
|
||||
for (@PsiModifier.ModifierConstant String keyword : keywords) {
|
||||
if (list.hasExplicitModifier(keyword)) {
|
||||
containModifierFlag = true;
|
||||
break;
|
||||
@@ -115,19 +113,19 @@ public class ModifierChooser {
|
||||
|
||||
private static boolean shouldSuggestModifiers(PsiElement element) {
|
||||
PsiElement parent = element.getParent();
|
||||
while(parent != null && (parent instanceof PsiJavaCodeReferenceElement
|
||||
|| parent instanceof PsiErrorElement || parent instanceof PsiTypeElement
|
||||
|| parent instanceof PsiMethod || parent instanceof PsiVariable
|
||||
|| parent instanceof PsiDeclarationStatement || parent instanceof PsiImportList
|
||||
|| parent instanceof PsiDocComment
|
||||
|| element.getText().equals(parent.getText()))){
|
||||
while (parent != null && (parent instanceof PsiJavaCodeReferenceElement ||
|
||||
parent instanceof PsiErrorElement || parent instanceof PsiTypeElement ||
|
||||
parent instanceof PsiMethod || parent instanceof PsiVariable ||
|
||||
parent instanceof PsiDeclarationStatement || parent instanceof PsiImportList ||
|
||||
parent instanceof PsiDocComment ||
|
||||
element.getText().equals(parent.getText()))) {
|
||||
parent = parent.getParent();
|
||||
if (parent instanceof JspClassLevelDeclarationStatement) {
|
||||
parent = parent.getContext();
|
||||
}
|
||||
}
|
||||
|
||||
if(parent == null) return false;
|
||||
if (parent == null) return false;
|
||||
|
||||
PsiElement prev = FilterPositionUtil.searchNonSpaceNonCommentBack(element);
|
||||
|
||||
@@ -139,5 +137,4 @@ public class ModifierChooser {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
interface Foo {
|
||||
String foo() def<caret>
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
interface Foo {
|
||||
String foo() default <caret>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
interface I {
|
||||
<caret>
|
||||
}
|
||||
+10
-7
@@ -27,12 +27,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class KeywordCompletionTest extends LightCompletionTestCase {
|
||||
private static final String BASE_PATH = "/codeInsight/completion/keywords";
|
||||
|
||||
private static final String[] FILE_SCOPE_KEYWORDS = new String[]{
|
||||
"package", "public", "private", "import", "final", "class", "interface", "abstract", "enum", null};
|
||||
private static final String[] CLASS_SCOPE_KEYWORDS = new String[]{
|
||||
"public", "private", "protected", "import", "final", "class", "interface", "abstract", "enum", null};
|
||||
private static final String[] CLASS_SCOPE_KEYWORDS_2 = new String[]{
|
||||
"package", "public", "private", "protected", "transient", "volatile", "static", "import", "final", "class", "interface", "abstract"};
|
||||
private static final String[] FILE_SCOPE_KEYWORDS = {
|
||||
"package", "public", "private", "import", "final", "class", "interface", "abstract", "enum", "default", null};
|
||||
private static final String[] CLASS_SCOPE_KEYWORDS = {
|
||||
"public", "private", "protected", "import", "final", "class", "interface", "abstract", "enum", "default", null};
|
||||
private static final String[] CLASS_SCOPE_KEYWORDS_2 = {
|
||||
"package", "public", "private", "protected", "transient", "volatile", "static", "import", "final", "class", "interface", "abstract", "default"};
|
||||
private static final String[] INTERFACE_SCOPE_KEYWORDS = {
|
||||
"package", "public", "private", "protected", "transient", "volatile", "static", "import", "final", "class", "interface", "abstract", "default"};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -46,6 +48,7 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
|
||||
public void testClassScope2() throws Exception { doTest(4, CLASS_SCOPE_KEYWORDS); }
|
||||
public void testClassScope3() throws Exception { doTest(0, CLASS_SCOPE_KEYWORDS); }
|
||||
public void testClassScope4() throws Exception { doTest(10, CLASS_SCOPE_KEYWORDS_2); }
|
||||
public void testInterfaceScope() throws Exception { doTest(8, INTERFACE_SCOPE_KEYWORDS); }
|
||||
public void testAfterAnnotations() throws Exception { doTest(6, "public", "final", "class", "interface", "abstract", "enum", null); }
|
||||
public void testExtends1() throws Exception { doTest(2, "extends", "implements", null); }
|
||||
public void testExtends2() throws Exception { doTest(1, "extends", "implements", "AAA", "BBB", "instanceof"); }
|
||||
@@ -96,7 +99,6 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
|
||||
public void testContinue() throws Exception { doTest(false); }
|
||||
public void testThrowsOnSeparateLine() throws Exception { doTest(true); }
|
||||
public void testDefaultInAnno() throws Exception { doTest(false); }
|
||||
public void testDefaultInExtMethod() throws Exception { doTest(false); }
|
||||
public void testNullInMethodCall() throws Exception { doTest(true); }
|
||||
public void testNullInMethodCall2() throws Exception { doTest(false); }
|
||||
public void testNewInMethodRefs() throws Exception { doTest(1, "new"); }
|
||||
@@ -127,6 +129,7 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
|
||||
checkResultByFile(BASE_PATH + "/" + getTestName(true) + "_after.java");
|
||||
}
|
||||
|
||||
// todo: check included/excluded variants separately
|
||||
protected void doTest(int finalCount, @NonNls String... values) {
|
||||
configureByFile(BASE_PATH + "/" + getTestName(true) + ".java");
|
||||
testByCount(finalCount, values);
|
||||
|
||||
Reference in New Issue
Block a user