mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-intentions] IDEA-301288 Suggest to make variable effectively final moving assignment to the branch without assignment
GitOrigin-RevId: c9953f2df87f2fa35ed97be97e48cd6240ee8fae
This commit is contained in:
committed by
intellij-monorepo-bot
parent
600fce247f
commit
24511394c3
@@ -618,4 +618,5 @@ inspection.redundant.requires.statement.message.java.base.implicitly.required='j
|
||||
reassign.variable.display.name=Reassigned variable
|
||||
intention.family.name.remove.repeating.call=Remove repeating call
|
||||
intention.name.remove.repeating.call=Remove repeating call ''{0}()''
|
||||
intention.family.name.replace.with.expression=Replace with expression
|
||||
intention.family.name.replace.with.expression=Replace with expression
|
||||
intention.name.make.variable.effectively.final=Make variable effectively final
|
||||
@@ -617,4 +617,10 @@ public abstract class QuickFixFactory {
|
||||
public abstract @NotNull IntentionAction createConvertAnonymousToInnerAction(@NotNull PsiAnonymousClass anonymousClass);
|
||||
|
||||
public abstract @NotNull IntentionAction createSplitSwitchBranchWithSeveralCaseValuesAction();
|
||||
|
||||
/**
|
||||
* @param variable variable to make an effectively final
|
||||
* @return a fix that refactors code to make variable effectively final when possible. Null, if it cannot create such a fix.
|
||||
*/
|
||||
public abstract @Nullable IntentionAction createMakeVariableEffectivelyFinalFix(@NotNull PsiVariable variable);
|
||||
}
|
||||
+1
@@ -734,6 +734,7 @@ public final class HighlightControlFlowUtil {
|
||||
String text = JavaErrorBundle.message("lambda.variable.must.be.final");
|
||||
HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(context).descriptionAndTooltip(text).create();
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createVariableAccessFromInnerClassFix(variable, lambdaExpression));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createMakeVariableEffectivelyFinalFix(variable));
|
||||
return ErrorFixExtensionPoint.registerFixes(highlightInfo, context, "lambda.variable.must.be.final");
|
||||
}
|
||||
}
|
||||
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.BlockUtils;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.java.analysis.JavaAnalysisBundle;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import one.util.streamex.MoreCollectors;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MakeVarEffectivelyFinalFix extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction {
|
||||
private MakeVarEffectivelyFinalFix(@NotNull PsiLocalVariable variable) {
|
||||
super(variable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
if (!(startElement instanceof PsiLocalVariable local)) return;
|
||||
EffectivelyFinalFixer fixer = ContainerUtil.find(EffectivelyFinalFixer.values(), f -> f.isAvailable(local));
|
||||
if (fixer == null) return;
|
||||
fixer.fix(local);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getText() {
|
||||
return JavaAnalysisBundle.message("intention.name.make.variable.effectively.final");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
public static @Nullable MakeVarEffectivelyFinalFix createFix(@NotNull PsiVariable variable) {
|
||||
if (!(variable instanceof PsiLocalVariable local)) return null;
|
||||
if (!ContainerUtil.exists(EffectivelyFinalFixer.values(), f -> f.isAvailable(local))) return null;
|
||||
return new MakeVarEffectivelyFinalFix(local);
|
||||
}
|
||||
|
||||
enum EffectivelyFinalFixer {
|
||||
MOVE_INITIALIZER_TO_IF_BRANCH {
|
||||
@Override
|
||||
boolean isAvailable(@NotNull PsiLocalVariable var) {
|
||||
PsiExpression initializer = var.getInitializer();
|
||||
if (!ExpressionUtils.isSafelyRecomputableExpression(initializer)) return false;
|
||||
if (refersToNonFinalLocal(initializer)) return false;
|
||||
Branched branched = extractInitMode(var);
|
||||
// Do not add too many branches
|
||||
return branched != null && branched.numberOfNonInitializedBranches() <= 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
void fix(@NotNull PsiLocalVariable var) {
|
||||
PsiExpression initializer = Objects.requireNonNull(var.getInitializer());
|
||||
Branched branched = Objects.requireNonNull(extractInitMode(var));
|
||||
PsiStatement statement = JavaPsiFacade.getElementFactory(var.getProject())
|
||||
.createStatementFromText(var.getName() + "=" + initializer.getText() + ";", null);
|
||||
branched.addInitializer(statement);
|
||||
initializer.delete();
|
||||
}
|
||||
};
|
||||
abstract boolean isAvailable(@NotNull PsiLocalVariable var);
|
||||
|
||||
abstract void fix(@NotNull PsiLocalVariable var);
|
||||
}
|
||||
|
||||
private static boolean refersToNonFinalLocal(PsiExpression initializer) {
|
||||
if (initializer instanceof PsiReferenceExpression ref && ref.resolve() instanceof PsiVariable refTarget) {
|
||||
if (PsiUtil.isJvmLocalVariable(refTarget) && !refTarget.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
PsiElement block = PsiUtil.getVariableCodeBlock(refTarget, null);
|
||||
return block == null || !HighlightControlFlowUtil.isEffectivelyFinal(refTarget, block, null);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Branched extractInitMode(@NotNull PsiLocalVariable var) {
|
||||
List<PsiExpressionStatement> initializers = initializers(var);
|
||||
if (initializers.isEmpty()) return null;
|
||||
if (!(var.getParent() instanceof PsiDeclarationStatement decl)) return null;
|
||||
if (!(decl.getParent() instanceof PsiCodeBlock block)) return null;
|
||||
PsiElement commonParent = PsiTreeUtil.findCommonParent(initializers);
|
||||
PsiIfStatement ifStatement = getTopLevelIfStatement(block, commonParent);
|
||||
if (ifStatement == null) return null;
|
||||
InitMode mode = StreamEx.of(initializers)
|
||||
.map(initStatement -> InitMode.create(initStatement, ifStatement))
|
||||
.collect(MoreCollectors.reducingWithZero(ExactMode.BOTTOM, ExactMode.NOT_INITIALIZED, InitMode::join));
|
||||
if (!(mode instanceof Branched branched)) return null;
|
||||
return branched;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiIfStatement getTopLevelIfStatement(PsiCodeBlock block, PsiElement commonParent) {
|
||||
while (true) {
|
||||
PsiIfStatement ifStatement = PsiTreeUtil.getNonStrictParentOfType(commonParent, PsiIfStatement.class);
|
||||
if (ifStatement == null) return null;
|
||||
PsiElement parent = ifStatement.getParent();
|
||||
if (parent == block) return ifStatement;
|
||||
commonParent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
private static @NotNull List<PsiExpressionStatement> initializers(@NotNull PsiLocalVariable var) {
|
||||
PsiElement block = PsiUtil.getVariableCodeBlock(var, null);
|
||||
if (block == null) return List.of();
|
||||
List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(var, block);
|
||||
List<PsiExpressionStatement> initializers = new ArrayList<>();
|
||||
for (PsiReferenceExpression reference : references) {
|
||||
if (!PsiUtil.isAccessedForWriting(reference)) continue;
|
||||
if (!(reference.getParent() instanceof PsiAssignmentExpression assign) || assign.getOperationTokenType() != JavaTokenType.EQ) {
|
||||
return List.of();
|
||||
}
|
||||
if (!(assign.getParent() instanceof PsiExpressionStatement statement)) return List.of();
|
||||
initializers.add(statement);
|
||||
}
|
||||
return initializers;
|
||||
}
|
||||
|
||||
sealed interface InitMode {
|
||||
@NotNull InitMode join(@NotNull InitMode nextMode);
|
||||
|
||||
int numberOfNonInitializedBranches();
|
||||
|
||||
private static InitMode fromInitializer(@NotNull PsiStatement statement, @NotNull InitMode origMode) {
|
||||
if (statement.getParent() instanceof PsiCodeBlock codeBlock && codeBlock.getParent() instanceof PsiBlockStatement block) {
|
||||
statement = block;
|
||||
}
|
||||
if (statement.getParent() instanceof PsiIfStatement ifStatement) {
|
||||
if (ifStatement.getThenBranch() == statement) {
|
||||
return new Branched(ifStatement, origMode, ExactMode.NOT_INITIALIZED);
|
||||
} else {
|
||||
return new Branched(ifStatement, ExactMode.NOT_INITIALIZED, origMode);
|
||||
}
|
||||
}
|
||||
return ExactMode.BOTTOM;
|
||||
}
|
||||
|
||||
static @NotNull InitMode create(@NotNull PsiExpressionStatement statement, @NotNull PsiIfStatement topStatement) {
|
||||
PsiStatement current = statement;
|
||||
InitMode curMode = ExactMode.INITIALIZED;
|
||||
while (current != topStatement) {
|
||||
curMode = fromInitializer(current, curMode);
|
||||
if (curMode instanceof Branched branched) {
|
||||
current = branched.ifStatement();
|
||||
} else {
|
||||
return ExactMode.BOTTOM;
|
||||
}
|
||||
}
|
||||
return curMode;
|
||||
}
|
||||
}
|
||||
|
||||
enum ExactMode implements InitMode {
|
||||
INITIALIZED, NOT_INITIALIZED, BOTTOM;
|
||||
|
||||
@Override
|
||||
public @NotNull InitMode join(@NotNull InitMode nextMode) {
|
||||
if (nextMode == NOT_INITIALIZED) return this;
|
||||
if (this == BOTTOM || this == INITIALIZED) return BOTTOM;
|
||||
return nextMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int numberOfNonInitializedBranches() {
|
||||
return this == NOT_INITIALIZED ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
record Branched(@NotNull PsiIfStatement ifStatement, @NotNull InitMode thenBranch, @NotNull InitMode elseBranch) implements InitMode {
|
||||
@Override
|
||||
public @NotNull InitMode join(@NotNull InitMode nextMode) {
|
||||
if (nextMode == ExactMode.NOT_INITIALIZED) return this;
|
||||
if (!(nextMode instanceof Branched branched)) return ExactMode.BOTTOM;
|
||||
if (ifStatement() != branched.ifStatement()) return ExactMode.BOTTOM;
|
||||
InitMode newThen = thenBranch().join(branched.thenBranch());
|
||||
InitMode newElse = elseBranch().join(branched.elseBranch());
|
||||
if (newThen == ExactMode.BOTTOM || newElse == ExactMode.BOTTOM) return ExactMode.BOTTOM;
|
||||
if (newThen == newElse) return newThen;
|
||||
return new Branched(ifStatement(), newThen, newElse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int numberOfNonInitializedBranches() {
|
||||
return thenBranch().numberOfNonInitializedBranches() + elseBranch().numberOfNonInitializedBranches();
|
||||
}
|
||||
|
||||
void addInitializer(@NotNull PsiStatement statement) {
|
||||
if (thenBranch() == ExactMode.NOT_INITIALIZED) {
|
||||
PsiStatement branch = ifStatement().getThenBranch();
|
||||
if (branch == null) {
|
||||
ifStatement().setThenBranch(JavaPsiFacade.getElementFactory(ifStatement().getProject()).createStatementFromText("{}", null));
|
||||
branch = Objects.requireNonNull(ifStatement().getThenBranch());
|
||||
}
|
||||
BlockUtils.addBefore(branch, statement);
|
||||
} else if (thenBranch() instanceof Branched branched) {
|
||||
branched.addInitializer(statement);
|
||||
}
|
||||
if (elseBranch() == ExactMode.NOT_INITIALIZED) {
|
||||
PsiStatement branch = ifStatement().getElseBranch();
|
||||
if (branch == null) {
|
||||
ifStatement().setElseBranch(JavaPsiFacade.getElementFactory(ifStatement().getProject()).createStatementFromText("{}", null));
|
||||
branch = Objects.requireNonNull(ifStatement().getElseBranch());
|
||||
}
|
||||
BlockUtils.addBefore(branch, statement);
|
||||
}
|
||||
else if (elseBranch() instanceof Branched branched) {
|
||||
branched.addInitializer(statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -1178,4 +1178,9 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
public @NotNull IntentionAction createSplitSwitchBranchWithSeveralCaseValuesAction() {
|
||||
return new SplitSwitchBranchWithSeveralCaseValuesAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable IntentionAction createMakeVariableEffectivelyFinalFix(@NotNull PsiVariable variable) {
|
||||
return MakeVarEffectivelyFinalFix.createFix(variable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,17 @@ public final class BlockUtils {
|
||||
*/
|
||||
public static PsiStatement addBefore(PsiStatement anchor, PsiStatement... newStatements) {
|
||||
if (newStatements.length == 0) throw new IllegalArgumentException();
|
||||
if (anchor instanceof PsiBlockStatement) {
|
||||
PsiCodeBlock codeBlock = ((PsiBlockStatement)anchor).getCodeBlock();
|
||||
PsiJavaToken brace = codeBlock.getLBrace();
|
||||
if (brace != null) {
|
||||
PsiElement result = brace;
|
||||
for (PsiStatement statement : newStatements) {
|
||||
result = codeBlock.addAfter(statement, result);
|
||||
}
|
||||
return (PsiStatement)result;
|
||||
}
|
||||
}
|
||||
PsiStatement oldStatement = anchor;
|
||||
PsiElement parent = oldStatement.getParent();
|
||||
while (parent instanceof PsiLabeledStatement) {
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a) {
|
||||
int x;
|
||||
if (a) {
|
||||
x = 1;
|
||||
}
|
||||
else {
|
||||
x = 0;
|
||||
System.out.println("hello");
|
||||
}
|
||||
Runnable r = () -> System.out.println(x);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c) {
|
||||
int x;
|
||||
if (a) {
|
||||
System.out.println("hello");
|
||||
x = 1;
|
||||
} else {
|
||||
x = 0;
|
||||
if (b) {
|
||||
System.out.println("hello2");
|
||||
} else if (c) {
|
||||
System.out.println("hello3");
|
||||
}
|
||||
}
|
||||
Runnable r = () -> System.out.println(x);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c) {
|
||||
int x;
|
||||
if (a) {
|
||||
if (b) {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
} else if (c) {
|
||||
x = 3;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
Runnable r = () -> System.out.println(x);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c) {
|
||||
int x;
|
||||
if (a) {
|
||||
if (b) {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
} else if (c) {
|
||||
x = 3;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
Runnable r = () -> System.out.println(x);
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c) {
|
||||
int x;
|
||||
if (a) {
|
||||
x = 0;
|
||||
System.out.println("hello");
|
||||
} else if (b) {
|
||||
x = 0;
|
||||
System.out.println("hello2");
|
||||
} else if (c) {
|
||||
x = 0;
|
||||
System.out.println("hello3");
|
||||
} else {
|
||||
x = 1;
|
||||
}
|
||||
Runnable r = () -> System.out.println(x);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a) {
|
||||
int x;
|
||||
if (a) {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
Runnable r = () -> System.out.println(x);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, int y) {
|
||||
int x;
|
||||
if (a) {
|
||||
x = 1;
|
||||
} else {
|
||||
x = y;
|
||||
}
|
||||
Runnable r = () -> System.out.println(x);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a) {
|
||||
int x = 0;
|
||||
if (a) {
|
||||
x = 1;
|
||||
}
|
||||
else System.out.println("hello");
|
||||
Runnable r = () -> System.out.println(<caret>x);
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c) {
|
||||
int x = 0;
|
||||
if (a) {
|
||||
System.out.println("hello");
|
||||
x = 1;
|
||||
} else if (b) {
|
||||
System.out.println("hello2");
|
||||
} else if (c) {
|
||||
System.out.println("hello3");
|
||||
}
|
||||
Runnable r = () -> System.out.println(<caret>x);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c) {
|
||||
int x = 0;
|
||||
if (a) {
|
||||
if (b) {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
} else if (c) {
|
||||
x = 3;
|
||||
}
|
||||
Runnable r = () -> System.out.println(<caret>x);
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c) {
|
||||
int x = 0;
|
||||
if (a) {
|
||||
if (b) {
|
||||
x = 1;
|
||||
}
|
||||
} else if (c) {
|
||||
x = 3;
|
||||
}
|
||||
Runnable r = () -> System.out.println(<caret>x);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c) {
|
||||
int x = 0;
|
||||
if (a) {
|
||||
System.out.println("hello");
|
||||
} else if (b) {
|
||||
System.out.println("hello2");
|
||||
} else if (c) {
|
||||
System.out.println("hello3");
|
||||
} else {
|
||||
x = 1;
|
||||
}
|
||||
Runnable r = () -> System.out.println(<caret>x);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a) {
|
||||
int x = 0;
|
||||
if (a) {
|
||||
x = 1;
|
||||
}
|
||||
Runnable r = () -> System.out.println(<caret>x);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Make variable effectively final" "false"
|
||||
class X {
|
||||
void test(boolean a, boolean b, boolean c, boolean d) {
|
||||
int x = 0;
|
||||
if (a) {
|
||||
System.out.println("hello");
|
||||
} else if (b) {
|
||||
System.out.println("hello2");
|
||||
} else if (c) {
|
||||
System.out.println("hello3");
|
||||
} else if (d) {
|
||||
System.out.println("hello4");
|
||||
} else {
|
||||
x = 1;
|
||||
}
|
||||
Runnable r = () -> System.out.println(<caret>x);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Make variable effectively final" "true-preview"
|
||||
class X {
|
||||
void test(boolean a, int y) {
|
||||
int x = y;
|
||||
if (a) {
|
||||
x = 1;
|
||||
}
|
||||
Runnable r = () -> System.out.println(<caret>x);
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.daemon.impl.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 MakeVarEffectivelyFinalFixTest extends LightQuickFixParameterizedTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_17;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/makeVarEffectivelyFinal";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user