Java: disallow introduce variable in interface field initializers (IDEA-369318)

GitOrigin-RevId: 9581036bab179eb78d908aff92da0517ccaaa328
This commit is contained in:
Bas Leijdekkers
2025-03-20 18:24:49 +00:00
committed by intellij-monorepo-bot
parent 081a0d95dc
commit 33d037c1fd
4 changed files with 20 additions and 1 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.refactoring.introduceVariable;
import com.intellij.codeInsight.CodeInsightUtil;
@@ -55,6 +55,7 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import one.util.streamex.EntryStream;
import one.util.streamex.StreamEx;
@@ -293,6 +294,15 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
showErrorMessage(project, editor, RefactoringBundle.getCannotRefactorMessage(errorMessage));
return false;
}
PsiExpression topLevelExpression = ExpressionUtils.getTopLevelExpression(expr);
if (topLevelExpression.getParent() instanceof PsiField f) {
PsiClass containingClass = f.getContainingClass();
if (containingClass != null && containingClass.isInterface()) {
String message = JavaRefactoringBundle.message("introduce.variable.message.cannot.extract.variable.in.interface");
showErrorMessage(project, editor, RefactoringBundle.getCannotRefactorMessage(message));
return false;
}
}
}
if (expr != null && expr.getParent() instanceof PsiExpressionStatement) {
@@ -0,0 +1,4 @@
interface DisallowInInterface {
int i = <selection>10</selection>;
}
@@ -393,6 +393,10 @@ public class IntroduceVariableTest extends LightJavaCodeInsightTestCase {
doTestWithFailure("input", "Object", "The selected expression refers to pattern variable 's', which will be out of scope.");
}
public void testDisallowInInterface() {
doTestWithFailure("", "", "Cannot extract variable in an interface.");
}
public void testOneLineLambdaVoidCompatible() {UiInterceptors.register(new ChooserInterceptor(null, Pattern.quote("Runnable: () -> {...}"))); doTest("c", false, false, false, JAVA_LANG_STRING); }
public void testOneLineLambdaValueCompatible() { doTest("c", false, false, false, "int"); }
public void testStatementsBeforeSuper() {
@@ -821,6 +821,7 @@ progress.title.collect.hierarchy=Collect ''{0}'' hierarchy
introduce.variable.message.change.semantics.warning=Extracting the selected expression changes the semantics of the surrounding expression.
introduce.variable.message.expression.refers.to.pattern.variable.declared.outside=The selected expression refers to pattern variable ''{0}'', which will be out of scope.
introduce.variable.message.cannot.extract.in.implicit.class=Cannot extract in implicitly declared class.
introduce.variable.message.cannot.extract.variable.in.interface=Cannot extract variable in an interface.
tooltip.cannot.inline.pattern.variable=Cannot inline pattern variable
inline.popup.highlight=Highlight {0} conflicting {0, choice, 1#write|2#writes}
inline.popup.ignore.conflicts=Ignore writes and continue