[postfix completion] IDEA-277334 Java 17 support: Postfix .switch doesn't work when selector expression is Object

Add tests for the switch postfix completion

GitOrigin-RevId: b1221d428e78221c3a2c3e128d24eefa4bd2bc0e
This commit is contained in:
Nikita Eshkeev
2021-09-09 01:24:05 +03:00
committed by intellij-monorepo-bot
parent cc6023df72
commit 8df26f2b6f
6 changed files with 66 additions and 7 deletions

View File

@@ -9,6 +9,8 @@ import com.intellij.java.JavaBundle;
import com.intellij.lang.surroundWith.Surrounder;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
@@ -27,7 +29,7 @@ import java.util.List;
import static com.intellij.openapi.util.Conditions.and;
public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase {
public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase implements DumbAware {
private static final Condition<PsiElement> SWITCH_TYPE = expression -> {
if (!(expression instanceof PsiExpression)) return false;
@@ -37,7 +39,7 @@ public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase
if (type == null) return false;
if (PsiType.INT.isAssignableFrom(type)) return true;
if (isEnumOrObjectOrSealed(type, expression)) return true;
if (isEnumOrObjectOrSealedClass(expression, type)) return true;
if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
PsiFile containingFile = expression.getContainingFile();
@@ -50,20 +52,32 @@ public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase
return false;
};
@Contract(pure=true)
private static boolean isEnumOrObjectOrSealed(@Nullable PsiType type, @NotNull PsiElement expression) {
@Contract(pure = true)
private static boolean isEnumOrObjectOrSealedClass(@NotNull PsiElement expression, @Nullable PsiType type) {
if (!(type instanceof PsiClassType)) return false;
final PsiResolveHelper resolver = JavaPsiFacade.getInstance(expression.getProject()).getResolveHelper();
final PsiClass psiClass = resolver.resolveReferencedClass(type.getCanonicalText(), null);
if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return true;
final PsiClass psiClass = getClassType(expression.getProject(), type);
if (psiClass == null) return false;
if (psiClass.isEnum()) return true;
if (!HighlightingFeature.PATTERNS_IN_SWITCH.isAvailable(expression)) return false;
return type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || psiClass.hasModifierProperty(PsiModifier.SEALED);
return CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass.getQualifiedName()) || psiClass.hasModifierProperty(PsiModifier.SEALED);
}
@Contract(pure = true)
private static @Nullable PsiClass getClassType(@NotNull Project project, @NotNull PsiType type) {
final PsiResolveHelper resolver = JavaPsiFacade.getInstance(project).getResolveHelper();
if (!DumbService.isDumb(project)) {
return resolver.resolveReferencedClass(type.getCanonicalText(), null);
}
return DumbService.getInstance(project)
.computeWithAlternativeResolveEnabled(() -> resolver.resolveReferencedClass(type.getCanonicalText(), null));
}
public SwitchStatementPostfixTemplate() {

View File

@@ -0,0 +1,6 @@
class Main {
int g(Object o) {
o.swit<caret>
}
}

View File

@@ -0,0 +1,8 @@
class Main {
int g(Object o) {
switch (o) {
<caret>
}
}
}

View File

@@ -0,0 +1,9 @@
class Main {
int h(Sealed o) {
o.swit<caret>
}
public static sealed interface Sealed {}
public static final class Variant {}
}

View File

@@ -0,0 +1,11 @@
class Main {
int h(Sealed o) {
switch (o) {
<caret>
}
}
public static sealed interface Sealed {}
public static final class Variant {}
}

View File

@@ -1,6 +1,7 @@
// 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.codeInsight.template.impl.LiveTemplateCompletionContributor
import com.intellij.testFramework.LightProjectDescriptor
import groovy.transform.CompileStatic
import org.jetbrains.annotations.NotNull
@@ -36,4 +37,14 @@ class NormalSwitchCompletionTest extends NormalCompletionTestCase {
void testCompletePatternVariableSwitchStmt() { doTest() }
void testCompletePatternVariableSwitchExpr() { doTest() }
void testCompleteSwitchObjectSelectorPostfix() { doTestPostfixCompletion() }
void testCompleteSwitchSealedSelectorPostfix() { doTestPostfixCompletion() }
private void doTestPostfixCompletion() {
LiveTemplateCompletionContributor.setShowTemplatesInTests(true, myFixture.testRootDisposable)
configure();
myFixture.type('\t' as char)
checkResult();
}
}