mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
[java][switch completion] IDEA-270439 Code completion for pattern matching in switch
Adjust the completion variants for switch statements and expressions GitOrigin-RevId: 05119897b0eb72bb875097cd197f376534d15db9
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1e0a217143
commit
afc2a8cd37
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
@@ -99,7 +99,7 @@ public class JavaKeywordCompletion {
|
||||
}
|
||||
|
||||
static final ElementPattern<PsiElement> START_SWITCH =
|
||||
psiElement().afterLeaf(psiElement().withText("{").withParents(PsiCodeBlock.class, PsiSwitchStatement.class));
|
||||
psiElement().afterLeaf(psiElement().withText("{").withParents(PsiCodeBlock.class, PsiSwitchBlock.class));
|
||||
|
||||
private static final ElementPattern<PsiElement> SUPER_OR_THIS_PATTERN =
|
||||
and(JavaSmartCompletionContributor.INSIDE_EXPRESSION,
|
||||
@@ -217,12 +217,14 @@ public class JavaKeywordCompletion {
|
||||
addKeyword(new OverridableSpace(createKeyword(PsiKeyword.ASSERT), TailType.INSERT_SPACE));
|
||||
}
|
||||
|
||||
TailType returnTail = getReturnTail(myPosition);
|
||||
LookupElement ret = createKeyword(PsiKeyword.RETURN);
|
||||
if (returnTail != TailType.NONE) {
|
||||
ret = new OverridableSpace(ret, returnTail);
|
||||
if (!psiElement().inside(PsiSwitchExpression.class).accepts(myPosition)) {
|
||||
TailType returnTail = getReturnTail(myPosition);
|
||||
LookupElement ret = createKeyword(PsiKeyword.RETURN);
|
||||
if (returnTail != TailType.NONE) {
|
||||
ret = new OverridableSpace(ret, returnTail);
|
||||
}
|
||||
addKeyword(ret);
|
||||
}
|
||||
addKeyword(ret);
|
||||
|
||||
if (psiElement().withText(";").withSuperParent(2, PsiIfStatement.class).accepts(myPrevLeaf) ||
|
||||
psiElement().withText("}").withSuperParent(3, PsiIfStatement.class).accepts(myPrevLeaf)) {
|
||||
@@ -284,6 +286,19 @@ public class JavaKeywordCompletion {
|
||||
addClassLiteral();
|
||||
|
||||
addExtendsImplements();
|
||||
|
||||
addCaseNullToSwitch();
|
||||
}
|
||||
|
||||
private void addCaseNullToSwitch() {
|
||||
if (!isInsidePatternMatchingSwitch()) return;
|
||||
|
||||
addKeyword(createKeyword(PsiKeyword.NULL));
|
||||
}
|
||||
|
||||
private boolean isInsidePatternMatchingSwitch() {
|
||||
if (!HighlightingFeature.PATTERNS_IN_SWITCH.isAvailable(myPosition)) return false;
|
||||
return psiElement().withSuperParent(2, PsiCaseLabelElementList.class).accepts(myPosition);
|
||||
}
|
||||
|
||||
private void addVar() {
|
||||
@@ -349,6 +364,13 @@ public class JavaKeywordCompletion {
|
||||
addKeyword(LookupElementDecorator.withInsertHandler(
|
||||
new OverridableSpace(createKeyword(PsiKeyword.DEFAULT), TailTypes.forSwitchLabel(switchBlock)),
|
||||
ADJUST_LINE_OFFSET));
|
||||
if (HighlightingFeature.PATTERNS_IN_SWITCH.isAvailable(myPosition)) {
|
||||
final LookupElement caseNull = LookupElementBuilder.create(PsiKeyword.CASE + " " + PsiKeyword.NULL)
|
||||
.bold()
|
||||
.withAutoCompletionPolicy(AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE);
|
||||
final OverridableSpace element = new OverridableSpace(caseNull, TailTypes.forSwitchLabel(switchBlock));
|
||||
addKeyword(LookupElementDecorator.withInsertHandler(element, ADJUST_LINE_OFFSET));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +413,7 @@ public class JavaKeywordCompletion {
|
||||
private void addFinal() {
|
||||
PsiStatement statement = PsiTreeUtil.getParentOfType(myPosition, PsiExpressionStatement.class, PsiDeclarationStatement.class);
|
||||
if (statement != null && statement.getTextRange().getStartOffset() == myPosition.getTextRange().getStartOffset()) {
|
||||
if (!psiElement().withSuperParent(2, PsiSwitchStatement.class).afterLeaf("{").accepts(statement)) {
|
||||
if (!psiElement().withSuperParent(2, PsiSwitchBlock.class).afterLeaf("{").accepts(statement)) {
|
||||
PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(myPrevLeaf, PsiTryStatement.class);
|
||||
if (tryStatement == null ||
|
||||
tryStatement.getCatchSections().length > 0 ||
|
||||
@@ -475,10 +497,8 @@ public class JavaKeywordCompletion {
|
||||
if (myPosition.getParent() instanceof PsiReferenceExpression) {
|
||||
PsiExpression qualifier = ((PsiReferenceExpression)myPosition.getParent()).getQualifierExpression();
|
||||
PsiClass qualifierClass = PsiUtil.resolveClassInClassTypeOnly(qualifier == null ? null : qualifier.getType());
|
||||
if (qualifierClass != null &&
|
||||
ContainerUtil.exists(qualifierClass.getAllInnerClasses(), inner -> canBeCreatedInQualifiedNew(qualifierClass, inner))) {
|
||||
return true;
|
||||
}
|
||||
return qualifierClass != null &&
|
||||
ContainerUtil.exists(qualifierClass.getAllInnerClasses(), inner -> canBeCreatedInQualifiedNew(qualifierClass, inner));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -730,10 +750,8 @@ public class JavaKeywordCompletion {
|
||||
PsiType type = ((PsiLocalVariable) position.getParent()).getType();
|
||||
if (type instanceof PsiClassType && ((PsiClassType) type).resolve() == null) {
|
||||
PsiElement grandParent = position.getParent().getParent();
|
||||
if (!(grandParent instanceof PsiDeclarationStatement) || !(grandParent.getParent() instanceof PsiForStatement) ||
|
||||
((PsiForStatement) grandParent.getParent()).getInitialization() != grandParent) {
|
||||
return true;
|
||||
}
|
||||
return !(grandParent instanceof PsiDeclarationStatement) || !(grandParent.getParent() instanceof PsiForStatement) ||
|
||||
((PsiForStatement)grandParent.getParent()).getInitialization() != grandParent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -926,9 +944,7 @@ public class JavaKeywordCompletion {
|
||||
psiElement().afterLeaf(".")).accepts(position)) {
|
||||
PsiElement stmt = position.getParent().getParent();
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)stmt.getParent();
|
||||
if (ifStatement.getElseBranch() == stmt || ifStatement.getThenBranch() == stmt) {
|
||||
return true;
|
||||
}
|
||||
return ifStatement.getElseBranch() == stmt || ifStatement.getThenBranch() == stmt;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
class Main {
|
||||
|
||||
int f(Object o) {
|
||||
return switch(o) {
|
||||
case Integer i, nul<caret>
|
||||
}
|
||||
}
|
||||
|
||||
int g(Object o) {
|
||||
return switch(o) {
|
||||
case nul<caret>, Integer i
|
||||
}
|
||||
}
|
||||
|
||||
int h(Object o) {
|
||||
return switch(o) {
|
||||
case nul<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
class Main {
|
||||
|
||||
int f(Object o) {
|
||||
return switch(o) {
|
||||
case Integer i, null<caret>
|
||||
}
|
||||
}
|
||||
|
||||
int g(Object o) {
|
||||
return switch(o) {
|
||||
case null<caret>, Integer i
|
||||
}
|
||||
}
|
||||
|
||||
int h(Object o) {
|
||||
return switch(o) {
|
||||
case null<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
class Main {
|
||||
|
||||
void f(Object o) {
|
||||
switch(o) {
|
||||
case Integer i, nul<caret>
|
||||
}
|
||||
}
|
||||
|
||||
void g(Object o) {
|
||||
switch(o) {
|
||||
case nul<caret>, Integer i
|
||||
}
|
||||
}
|
||||
|
||||
void h(Object o) {
|
||||
switch(o) {
|
||||
case nul<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
class Main {
|
||||
|
||||
void f(Object o) {
|
||||
switch(o) {
|
||||
case Integer i, null<caret>
|
||||
}
|
||||
}
|
||||
|
||||
void g(Object o) {
|
||||
switch(o) {
|
||||
case null<caret>, Integer i
|
||||
}
|
||||
}
|
||||
|
||||
void h(Object o) {
|
||||
switch(o) {
|
||||
case null<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
|
||||
class Main {
|
||||
int f(Object o) {
|
||||
return switch(o) {
|
||||
case Integer integer && inte<caret>, null
|
||||
}
|
||||
}
|
||||
|
||||
int g(Object o) {
|
||||
return switch(o) {
|
||||
case null, Integer integer && inte<caret>
|
||||
}
|
||||
}
|
||||
|
||||
int h(Object o) {
|
||||
return switch(o) {
|
||||
case Integer integer && inte<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
|
||||
class Main {
|
||||
int f(Object o) {
|
||||
return switch(o) {
|
||||
case Integer integer && integer<caret>, null
|
||||
}
|
||||
}
|
||||
|
||||
int g(Object o) {
|
||||
return switch(o) {
|
||||
case null, Integer integer && integer<caret>
|
||||
}
|
||||
}
|
||||
|
||||
int h(Object o) {
|
||||
return switch(o) {
|
||||
case Integer integer && integer<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
|
||||
class Main {
|
||||
void f(Object o) {
|
||||
switch(o) {
|
||||
case Integer integer && inte<caret>, null
|
||||
}
|
||||
}
|
||||
|
||||
void g(Object o) {
|
||||
switch(o) {
|
||||
case null, Integer integer && inte<caret>
|
||||
}
|
||||
}
|
||||
|
||||
void h(Object o) {
|
||||
switch(o) {
|
||||
case Integer integer && inte<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
|
||||
class Main {
|
||||
void f(Object o) {
|
||||
switch(o) {
|
||||
case Integer integer && integer<caret>, null
|
||||
}
|
||||
}
|
||||
|
||||
void g(Object o) {
|
||||
switch(o) {
|
||||
case null, Integer integer && integer<caret>
|
||||
}
|
||||
}
|
||||
|
||||
void h(Object o) {
|
||||
switch(o) {
|
||||
case Integer integer && integer<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
|
||||
class Main {
|
||||
int f(Object o) {
|
||||
return switch(o) {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
|
||||
class Main {
|
||||
void f(Object o) {
|
||||
switch(o) {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -29,4 +29,9 @@ class NormalSwitchCompletionTest extends NormalCompletionTestCase {
|
||||
void testCompleteConstantInSwitchExpr() { doTest() }
|
||||
void testCompleteConstantInSwitchStmt() { doTest() }
|
||||
|
||||
void testCompleteNullInSwitchStmt() { doTest() }
|
||||
void testCompleteNullInSwitchExpr() { doTest() }
|
||||
|
||||
void testCompletePatternVariableSwitchStmt() { doTest() }
|
||||
void testCompletePatternVariableSwitchExpr() { doTest() }
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.java.codeInsight.completion
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.codeInsight.completion.LightFixtureCompletionTestCase
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.annotations.NotNull
|
||||
|
||||
@CompileStatic
|
||||
class NormalSwitchCompletionVariantsTest extends LightFixtureCompletionTestCase {
|
||||
private static final String[] VARIANTS = ["case", "case null", "default"]
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/normal/variants/"
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_17
|
||||
}
|
||||
|
||||
void testCompletionVariantsInStmt() { doTest() }
|
||||
void testCompletionVariantsInExpr() { doTest() }
|
||||
|
||||
void doTest() {
|
||||
myFixture.configureByFile(getTestName(false) + ".java")
|
||||
myFixture.complete(CompletionType.BASIC)
|
||||
|
||||
final List<String> lookupElementStrings = myFixture.getLookupElementStrings()
|
||||
assertSameElements(lookupElementStrings, VARIANTS)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user