mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 10:20:15 +07:00
IDEA-277338 - fixed the description for malformed ref expressions which can be replaced with type pattern in switch, added the quick-fix
GitOrigin-RevId: c34d26c8dd7f3dfb079adeb49811d64e1bd093fa
This commit is contained in:
committed by
intellij-monorepo-bot
parent
986f038427
commit
6e19d89001
@@ -320,6 +320,11 @@ public abstract class QuickFixFactory {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction createReplaceWithTypePatternFix(@NotNull PsiReferenceExpression exprToReplace,
|
||||
@NotNull PsiClass resolvedExprClass,
|
||||
@NotNull String patternVarName);
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction createStaticImportMethodFix(@NotNull PsiMethodCallExpression call);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
|
||||
import com.intellij.psi.impl.light.LightRecordMethod;
|
||||
@@ -66,6 +67,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import com.siyeh.ig.psiutils.VariableNameGenerator;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -2056,6 +2058,21 @@ public final class HighlightUtil {
|
||||
return checkAssignability(componentType, initializerType, expression, initializer);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkPatternVariableRequired(@NotNull PsiReferenceExpression expression,
|
||||
@NotNull JavaResolveResult resultForIncompleteCode) {
|
||||
if (!(expression.getParent() instanceof PsiCaseLabelElementList)) return null;
|
||||
PsiClass resolved = tryCast(resultForIncompleteCode.getElement(), PsiClass.class);
|
||||
if (resolved == null) return null;
|
||||
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
|
||||
.descriptionAndTooltip(JavaErrorBundle.message("type.pattern.expected")).create();
|
||||
if (info != null) {
|
||||
String patternVarName = new VariableNameGenerator(expression, VariableKind.LOCAL_VARIABLE).byName("ignored").generate(true);
|
||||
QuickFixAction.registerQuickFixAction(info, getFixFactory().createReplaceWithTypePatternFix(expression, resolved, patternVarName));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
static HighlightInfo checkExpressionRequired(@NotNull PsiReferenceExpression expression,
|
||||
@NotNull JavaResolveResult resultForIncompleteCode) {
|
||||
if (expression.getNextSibling() instanceof PsiErrorElement) return null;
|
||||
|
||||
@@ -1449,6 +1449,10 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
if (!myHolder.hasErrorResults() && resultForIncompleteCode != null && HighlightingFeature.PATTERNS_IN_SWITCH.isAvailable(expression)) {
|
||||
myHolder.add(HighlightUtil.checkPatternVariableRequired(expression, resultForIncompleteCode));
|
||||
}
|
||||
|
||||
if (!myHolder.hasErrorResults() && resultForIncompleteCode != null) {
|
||||
myHolder.add(HighlightUtil.checkExpressionRequired(expression, resultForIncompleteCode));
|
||||
}
|
||||
|
||||
@@ -409,4 +409,5 @@ implement.or.extend.fix.extend.text=Extend ''{0}''
|
||||
|
||||
seal.class.from.permits.list.fix=Seal inheritor
|
||||
|
||||
unwrap.array.initializer.fix=Replace array initializer with its element
|
||||
unwrap.array.initializer.fix=Replace array initializer with its element
|
||||
replace.with.type.pattern.fix=Replace with type pattern
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
|
||||
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
|
||||
import com.intellij.codeInspection.CommonQuickFixBundle;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ReplaceWithTypePatternFix extends BaseIntentionAction {
|
||||
@NotNull private final SmartPsiElementPointer<PsiReferenceExpression> myExprToReplace;
|
||||
@NotNull private final SmartPsiElementPointer<PsiClass> myResolvedExprClass;
|
||||
@NlsSafe private final String myPatternVarName;
|
||||
|
||||
public ReplaceWithTypePatternFix(@NotNull PsiReferenceExpression exprToReplace, @NotNull PsiClass resolvedExprClass,
|
||||
@NotNull String patternVarName) {
|
||||
myExprToReplace = SmartPointerManager.createPointer(exprToReplace);
|
||||
myResolvedExprClass = SmartPointerManager.createPointer(resolvedExprClass);
|
||||
myPatternVarName = patternVarName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
PsiReferenceExpression expression = getExprToReplace();
|
||||
if (expression == null) return false;
|
||||
return HighlightingFeature.PATTERNS_IN_SWITCH.isAvailable(expression) && expression.getParent() instanceof PsiCaseLabelElementList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
PsiReferenceExpression exprToReplace = getExprToReplace();
|
||||
if (exprToReplace == null) return;
|
||||
PsiClass resolvedExprClass = getResolvedExprClass();
|
||||
if (resolvedExprClass == null) return;
|
||||
PsiExpression newExpr = JavaPsiFacade.getElementFactory(resolvedExprClass.getProject())
|
||||
.createExpressionFromText("x instanceof " + resolvedExprClass.getName() + " " + myPatternVarName, resolvedExprClass);
|
||||
if (newExpr instanceof PsiInstanceOfExpression) {
|
||||
exprToReplace.replace(Objects.requireNonNull(((PsiInstanceOfExpression)newExpr).getPattern()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getText() {
|
||||
PsiClass resolvedExprClass = getResolvedExprClass();
|
||||
if (resolvedExprClass == null) return getFamilyName();
|
||||
return CommonQuickFixBundle.message("fix.replace.with.x", resolvedExprClass.getName() + " " + myPatternVarName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return QuickFixBundle.message("replace.with.type.pattern.fix");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiReferenceExpression getExprToReplace() {
|
||||
return myExprToReplace.getElement();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiClass getResolvedExprClass() {
|
||||
return myResolvedExprClass.getElement();
|
||||
}
|
||||
}
|
||||
@@ -534,6 +534,13 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
return CreateConstructorFromUsage.generateConstructorActions(call);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IntentionAction createReplaceWithTypePatternFix(@NotNull PsiReferenceExpression exprToReplace,
|
||||
@NotNull PsiClass resolvedExprClass,
|
||||
@NotNull String patternVarName) {
|
||||
return new ReplaceWithTypePatternFix(exprToReplace, resolvedExprClass, patternVarName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createStaticImportMethodFix(@NotNull PsiMethodCallExpression call) {
|
||||
|
||||
@@ -245,6 +245,7 @@ package.local.symbol=''{0}'' is not public in ''{1}''. Cannot be accessed from o
|
||||
visibility.access.problem=Cannot access ''{0}'' in ''{1}''
|
||||
visibility.module.access.problem=Access to ''{0}'' in ''{1}'' is prevented by {2}
|
||||
array.type.expected=Array type expected; found: ''{0}''
|
||||
type.pattern.expected=Type pattern expected
|
||||
expression.expected=Expression expected
|
||||
array.initializer.not.allowed=Array initializer is not allowed here
|
||||
case.statement.outside.switch=Case statement outside switch
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
class Test {
|
||||
void test(Number n) {
|
||||
class MyNumber extends Number {
|
||||
@Override
|
||||
public int intValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int result;
|
||||
|
||||
switch (n) {
|
||||
case <error descr="Type pattern expected">MyNumber</error>: break;
|
||||
case <error descr="Type pattern expected">Integer</error><error descr="':' expected"> </error>break;
|
||||
case default: break;
|
||||
}
|
||||
result = switch (n) {
|
||||
case <error descr="Type pattern expected">MyNumber</error>: yield 1;
|
||||
case Float ignored: yield 2;
|
||||
case default: yield 3;
|
||||
};
|
||||
result = switch (n) {
|
||||
case <error descr="Type pattern expected">MyNumber</error> -> 1;
|
||||
case Float ignored -> 2;
|
||||
case default -> 3;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Replace with 'Integer ignored1'" "true"
|
||||
class Test {
|
||||
void test(Integer n, int ignored) {
|
||||
switch (n) {
|
||||
case Integer ignored1: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Replace with 'Integer ignored1'" "true"
|
||||
class Test {
|
||||
void test(Integer n) {
|
||||
switch (n) {
|
||||
case Integer ignored1:
|
||||
int ignored = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Replace with 'Integer ignored'" "true"
|
||||
class Test {
|
||||
void test(Integer n) {
|
||||
switch (n) {
|
||||
case Integer ignored: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Replace with 'Integer ignored1'" "true"
|
||||
class Test {
|
||||
void test(Integer n, int ignored) {
|
||||
switch (n) {
|
||||
case Integer<caret>: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Replace with 'Integer ignored1'" "true"
|
||||
class Test {
|
||||
void test(Integer n) {
|
||||
switch (n) {
|
||||
case Integer<caret>:
|
||||
int ignored = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Replace with 'Integer ignored'" "true"
|
||||
class Test {
|
||||
void test(Integer n) {
|
||||
switch (n) {
|
||||
case Integer<caret>: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,10 @@ public class LightPatternsForSwitchHighlightingTest extends LightJavaCodeInsight
|
||||
assertNotNull(myFixture.getAvailableIntention("Rename 's' to 'ignored'"));
|
||||
}
|
||||
|
||||
public void testMalformedReferenceExpression() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
myFixture.checkHighlighting();
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// 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.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ReplaceWithTypePatternFixTest extends LightQuickFixParameterizedTestCase {
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithPattern";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_17;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user