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

The switch statement postfix completion template used to be applied to either elements of the Object type or of a sealed class. This restriction was just a result of a mistake. This patch lifts this restriction and makes SwitchStatementPostfixTemplate truly DumbAware by resolving an expression's type with DumbModeAccessType bypassing the dumb mode if necessary.

GitOrigin-RevId: c2f82834ff4e6842d6d825f9ff994c288196291b
This commit is contained in:
Nikita Eshkeev
2021-09-10 16:46:29 +00:00
committed by intellij-monorepo-bot
parent 9c3ab2e377
commit a4da031bdf
3 changed files with 17 additions and 4 deletions
@@ -20,6 +20,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.indexing.DumbModeAccessType;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,12 +35,16 @@ public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase
private static final Condition<PsiElement> SWITCH_TYPE = expression -> {
if (!(expression instanceof PsiExpression)) return false;
PsiType type = ((PsiExpression)expression).getType();
final PsiType type = getType((PsiExpression)expression);
if (type == null) return false;
if (PsiType.INT.isAssignableFrom(type)) return true;
if (type instanceof PsiClassType) {
if (HighlightingFeature.PATTERNS_IN_SWITCH.isAvailable(expression)) return true;
if (isEnumOrObjectOrSealedClass(expression, type)) return true;
PsiClass psiClass = ((PsiClassType)type).resolve();
if (psiClass != null && psiClass.isEnum()) return true;
}
if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
PsiFile containingFile = expression.getContainingFile();
@@ -52,6 +57,14 @@ public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase
return false;
};
@Contract(pure = true)
private static @Nullable PsiType getType(@NotNull PsiExpression expression) {
if (!DumbService.isDumb(expression.getProject())) {
return expression.getType();
}
return DumbModeAccessType.RELIABLE_DATA_ONLY.ignoreDumbMode(expression::getType);
}
@Contract(pure = true)
private static boolean isEnumOrObjectOrSealedClass(@NotNull PsiElement expression, @Nullable PsiType type) {
if (!(type instanceof PsiClassType)) return false;
@@ -1,6 +1,6 @@
class Main {
int g(Object o) {
int g(CharSequence o) {
o.swit<caret>
}
}
@@ -1,6 +1,6 @@
class Main {
int g(Object o) {
int g(CharSequence o) {
switch (o) {
<caret>
}