[java-inspections] IDEA-371838 Convert SideEffectsMethodRefToLambdaFix to ModCommand

GitOrigin-RevId: 8e1fff8b05604adf5fe3e6dc853d8ac952b5a242
This commit is contained in:
Tagir Valeev
2025-04-29 13:01:39 +00:00
committed by intellij-monorepo-bot
parent 943fdcf538
commit 5fd8eb4a09
87 changed files with 210 additions and 301 deletions
@@ -2129,6 +2129,8 @@ lambda.can.be.replaced.with.anonymous.name=Lambda can be replaced with anonymous
lambda.can.be.replaced.with.anonymous.quickfix=Replace lambda with anonymous class
method.ref.can.be.replaced.with.lambda.name=Method reference can be replaced with lambda
method.ref.can.be.replaced.with.lambda.quickfix=Replace method reference with lambda
method.ref.can.be.replaced.with.lambda.quickfix.side.effects=Extract possible side effects into a variable
method.ref.can.be.replaced.with.lambda.quickfix.no.side.effects=Keep possible side effects inside lambda
try.statement.with.multiple.resources.name='try' statement with multiple resources can be split
try.statement.with.multiple.resources.quickfix=Split 'try' statement with multiple resources
multi.catch.can.be.split.name=Multi-catch can be split into separate catch blocks
@@ -2455,7 +2457,6 @@ use.equalsignorecase.for.case.insensitive.comparison=Use 'equalsIgnoreCase()' fo
use.contentequals=Use 'contentEquals()' for comparison with 'AbstractStringBuilder'
use.isblank.to.check.if.string.is.whitespace.or.empty=Use 'isBlank()' to check if a string is empty or only contains whitespace
make.class.final.fix.family.name=Make class final
side.effects.method.ref.to.lambda.fix.family.name={0} (side effects)
encapsulate.variable.fix.family.name=Encapsulate field
method.may.be.static.replaces.qualifiers.with.class.references.option=Quick-fix replaces instance qualifiers with class references
method.may.be.static.ignore.default.methods.option=Ignore 'default' methods
@@ -2,14 +2,7 @@
package com.intellij.refactoring.util;
import com.intellij.codeInspection.RedundantLambdaCodeBlockInspection;
import com.intellij.java.refactoring.JavaRefactoringBundle;
import com.intellij.lang.LanguageRefactoringSupport;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -19,8 +12,6 @@ import com.intellij.psi.impl.RecaptureTypeMapper;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.introduceField.ElementToWorkOn;
import com.intellij.refactoring.introduceVariable.JavaIntroduceVariableHandlerBase;
import com.intellij.util.Function;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
@@ -32,7 +23,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public final class LambdaRefactoringUtil {
private static final Logger LOG = Logger.getInstance(LambdaRefactoringUtil.class);
@@ -310,46 +303,6 @@ public final class LambdaRefactoringUtil {
}
}
/**
* Works for expression lambdas/one statement code block lambdas to ensures equivalent method ref -> lambda transformation.
*/
public static void removeSideEffectsFromLambdaBody(Editor editor, PsiLambdaExpression lambdaExpression) {
if (lambdaExpression != null && lambdaExpression.isValid()) {
final PsiElement body = lambdaExpression.getBody();
PsiExpression methodCall = LambdaUtil.extractSingleExpressionFromBody(body);
PsiExpression qualifierExpression = null;
if (methodCall instanceof PsiMethodCallExpression) {
qualifierExpression = ((PsiMethodCallExpression)methodCall).getMethodExpression().getQualifierExpression();
}
else if (methodCall instanceof PsiNewExpression) {
qualifierExpression = ((PsiNewExpression)methodCall).getQualifier();
}
if (qualifierExpression != null) {
final List<PsiElement> sideEffects = new ArrayList<>();
if (ExpressionUtils.isNewObject(qualifierExpression)) {
sideEffects.add(qualifierExpression);
}
else {
SideEffectChecker.checkSideEffects(qualifierExpression, sideEffects);
}
if (!sideEffects.isEmpty()) {
if (ApplicationManager.getApplication().isUnitTestMode() ||
Messages.showYesNoDialog(lambdaExpression.getProject(),
JavaRefactoringBundle.message("lambda.to.reference.side.effect.warning.message"),
JavaRefactoringBundle.message("side.effects.detected.title"), Messages.getQuestionIcon()) == Messages.YES) {
//ensure introduced before lambda
qualifierExpression.putUserData(ElementToWorkOn.PARENT, lambdaExpression);
RefactoringSupportProvider supportProvider = LanguageRefactoringSupport.getInstance().forLanguage(JavaLanguage.INSTANCE);
JavaIntroduceVariableHandlerBase handler = (JavaIntroduceVariableHandlerBase)supportProvider.getIntroduceVariableHandler();
assert handler != null;
handler.invoke(qualifierExpression.getProject(), editor, qualifierExpression);
}
}
}
}
}
/**
* Checks whether method reference can be converted to lambda without significant semantics change
* (i.e. method reference qualifier has no side effects)
@@ -1,35 +1,32 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.style;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.ide.DataManager;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.modcommand.ActionContext;
import com.intellij.modcommand.ModCommand;
import com.intellij.modcommand.Presentation;
import com.intellij.modcommand.PsiBasedModCommandAction;
import com.intellij.pom.java.JavaFeature;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLambdaExpression;
import com.intellij.psi.PsiMethodReferenceExpression;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.refactoring.util.LambdaRefactoringUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.ThreeState;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.CodeBlockSurrounder;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.SideEffectChecker;
import com.siyeh.ig.psiutils.VariableNameGenerator;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Set;
import static java.util.Objects.requireNonNull;
public final class MethodRefCanBeReplacedWithLambdaInspection extends BaseInspection {
@Override
@@ -48,16 +45,9 @@ public final class MethodRefCanBeReplacedWithLambdaInspection extends BaseInspec
}
@Override
protected @Nullable LocalQuickFix buildFix(Object... infos) {
protected @NotNull LocalQuickFix buildFix(Object... infos) {
final PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression)infos[0];
final boolean onTheFly = (Boolean)infos[1];
if (LambdaRefactoringUtil.canConvertToLambdaWithoutSideEffects(methodReferenceExpression)) {
return new MethodRefToLambdaFix();
}
else if (onTheFly) {
return new SideEffectsMethodRefToLambdaFix();
}
return null;
return LocalQuickFix.from(new SideEffectsMethodRefToLambdaFix(methodReferenceExpression));
}
private static class MethodRefToLambdaVisitor extends BaseInspectionVisitor {
@@ -65,72 +55,91 @@ public final class MethodRefCanBeReplacedWithLambdaInspection extends BaseInspec
public void visitMethodReferenceExpression(@NotNull PsiMethodReferenceExpression methodReferenceExpression) {
super.visitMethodReferenceExpression(methodReferenceExpression);
if (LambdaRefactoringUtil.canConvertToLambda(methodReferenceExpression)) {
registerError(methodReferenceExpression, methodReferenceExpression, isOnTheFly());
registerError(methodReferenceExpression, methodReferenceExpression);
}
}
}
private static class MethodRefToLambdaFix extends PsiUpdateModCommandQuickFix {
private static class SideEffectsMethodRefToLambdaFix extends PsiBasedModCommandAction<PsiMethodReferenceExpression> {
private final ThreeState myExtractSideEffect;
SideEffectsMethodRefToLambdaFix(@NotNull PsiMethodReferenceExpression methodRef) {
this(methodRef, ThreeState.UNSURE);
}
SideEffectsMethodRefToLambdaFix(@NotNull PsiMethodReferenceExpression methodRef, @NotNull ThreeState extractSideEffect) {
super(methodRef);
myExtractSideEffect = extractSideEffect;
}
@Override
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiMethodReferenceExpression element) {
String message = switch (myExtractSideEffect) {
case YES -> InspectionGadgetsBundle.message("method.ref.can.be.replaced.with.lambda.quickfix.side.effects");
case NO -> InspectionGadgetsBundle.message("method.ref.can.be.replaced.with.lambda.quickfix.no.side.effects");
case UNSURE -> InspectionGadgetsBundle.message("method.ref.can.be.replaced.with.lambda.quickfix");
};
return Presentation.of(message);
}
@Override
public @Nls @NotNull String getFamilyName() {
return InspectionGadgetsBundle.message("method.ref.can.be.replaced.with.lambda.quickfix");
}
@Override
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (element instanceof PsiMethodReferenceExpression methodRef) {
LambdaRefactoringUtil.convertMethodReferenceToLambda(methodRef, false, true);
protected @NotNull ModCommand perform(@NotNull ActionContext context, @NotNull PsiMethodReferenceExpression methodRef) {
boolean extractSideEffect;
if (myExtractSideEffect == ThreeState.UNSURE) {
if (possibleToExtractSideEffect(methodRef)) {
//noinspection DialogTitleCapitalization
return ModCommand.chooseAction(getFamilyName(),
new SideEffectsMethodRefToLambdaFix(methodRef, ThreeState.YES),
new SideEffectsMethodRefToLambdaFix(methodRef, ThreeState.NO));
}
extractSideEffect = false;
}
}
}
private static class SideEffectsMethodRefToLambdaFix extends InspectionGadgetsFix {
@Override
public @Nls @NotNull String getFamilyName() {
return ApplicationManager.getApplication().isUnitTestMode() ?
(InspectionGadgetsBundle.message("side.effects.method.ref.to.lambda.fix.family.name",
InspectionGadgetsBundle.message("method.ref.can.be.replaced.with.lambda.quickfix"))) :
InspectionGadgetsBundle.message("method.ref.can.be.replaced.with.lambda.quickfix");
}
@Override
public boolean startInWriteAction() {
return false;
}
@Override
public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull ProblemDescriptor previewDescriptor) {
PsiMethodReferenceExpression methodRef = ObjectUtils.tryCast(previewDescriptor.getPsiElement(), PsiMethodReferenceExpression.class);
if (methodRef == null) {
return IntentionPreviewInfo.EMPTY;
else {
extractSideEffect = myExtractSideEffect == ThreeState.YES && possibleToExtractSideEffect(methodRef);
}
LambdaRefactoringUtil.convertMethodReferenceToLambda(methodRef, false, true);
return IntentionPreviewInfo.DIFF;
if (!extractSideEffect) {
return ModCommand.psiUpdate(methodRef, mr -> LambdaRefactoringUtil.convertMethodReferenceToLambda(mr, false, true));
}
return ModCommand.psiUpdate(methodRef, (mr, updater) -> {
CodeBlockSurrounder surrounder = requireNonNull(CodeBlockSurrounder.forExpression(mr));
CodeBlockSurrounder.SurroundResult result = surrounder.surround();
PsiLambdaExpression lambdaExpression =
LambdaRefactoringUtil.convertMethodReferenceToLambda((PsiMethodReferenceExpression)result.getExpression(), false, true);
if (lambdaExpression == null) return;
PsiExpression methodCall = LambdaUtil.extractSingleExpressionFromBody(lambdaExpression.getBody());
PsiExpression qualifierExpression = null;
if (methodCall instanceof PsiMethodCallExpression call) {
qualifierExpression = call.getMethodExpression().getQualifierExpression();
}
else if (methodCall instanceof PsiNewExpression call) {
qualifierExpression = call.getQualifier();
}
if (qualifierExpression == null) return;
PsiType type = qualifierExpression.getType();
if (type == null) return;
List<String> varNames =
new VariableNameGenerator(result.getAnchor(), VariableKind.LOCAL_VARIABLE).byExpression(qualifierExpression).generateAll(true);
String name = varNames.get(0);
PsiElementFactory factory = JavaPsiFacade.getElementFactory(context.project());
PsiDeclarationStatement declaration = factory
.createVariableDeclarationStatement(name, type, qualifierExpression, result.getAnchor());
declaration = (PsiDeclarationStatement)result.getAnchor().getParent().addBefore(declaration, result.getAnchor());
PsiVariable declaredVariable = (PsiVariable)declaration.getDeclaredElements()[0];
qualifierExpression.replace(factory.createExpressionFromText(name, null));
updater.rename(declaredVariable, varNames);
});
}
@Override
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
if (element instanceof PsiMethodReferenceExpression methodRef) {
DataManager.getInstance()
.getDataContextFromFocusAsync()
.onSuccess(context -> {
final Editor editor = CommonDataKeys.EDITOR.getData(context);
if (editor != null) {
CommandProcessor.getInstance()
.executeCommand(project, () -> doFixAndRemoveSideEffects(editor, methodRef), getFamilyName(), null);
}
});
}
}
private static void doFixAndRemoveSideEffects(@NotNull Editor editor, @NotNull PsiMethodReferenceExpression methodReferenceExpression) {
if (!FileModificationService.getInstance().preparePsiElementsForWrite(methodReferenceExpression)) return;
final PsiLambdaExpression lambdaExpression =
WriteAction.compute(() -> LambdaRefactoringUtil.convertMethodReferenceToLambda(methodReferenceExpression, false, true));
if (lambdaExpression != null) {
LambdaRefactoringUtil.removeSideEffectsFromLambdaBody(editor, lambdaExpression);
}
private static boolean possibleToExtractSideEffect(@NotNull PsiMethodReferenceExpression methodRef) {
PsiExpression qualifier = methodRef.getQualifierExpression();
return qualifier != null && qualifier.getType() != null &&
(SideEffectChecker.mayHaveSideEffects(qualifier) || ExpressionUtils.isNewObject(qualifier)) &&
CodeBlockSurrounder.canSurround(methodRef);
}
}
}
@@ -1,14 +0,0 @@
class Test {
{
Runnable runnable = () -> new Runnable() {
{
}
public void run() {
System.out.println(this);
}
}.run();
runnable.run();
runnable.run();
}
}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
static void m(Integer i) { assertTrue(true); }
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
static void foo() {
Ar<String> a = p -> new String[p];
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
static void foo() {
Ar<String> a = p -> new String[p][];
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
public void test() {
Object i = null;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
static void foo() {
Cln j = ints -> ints.clone();
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
public class MyTest {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.List;
import java.util.stream.Stream;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.Comparator;
class MyTest {
void setComparator(Comparator<?> comparator) {}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
public class MyTest {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.*;
public class MyTest {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.*;
public class MyTest<T> {
@@ -0,0 +1,11 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
class Test {
boolean result;
{
HashSet<Object> objects = new HashSet<>();
result = Arrays.asList("a", "a").stream().allMatch(e -> objects.add(e));
}
}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda|->Keep possible side effects inside lambda" "true-preview"
import java.util.*;
class Test {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Test {
void test(){
class Local(){}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.*;
public class MyTest {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
class Test
{
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
public static class Bar {}
}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
MyTest() {}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest<X> {
MyTest(X x) {}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
interface I {
void m(Integer s);
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class MyTest {
static class Inner {
Inner(MyTest mt) {};
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class MyTest {
static class Inner {
Inner(MyTest outer) {};
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.IntConsumer;
public class Main {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.Function;
abstract class Result<V> {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
interface I {
void m(MyTest receiver);
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.Comparator;
class A {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
interface I { void foo(int i); }
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
class Bar {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
interface I {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class MyTest {
static interface SAM {
void m(Integer i);
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class Test<T> {
static void foo() {}
}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
static void m(Integer i) { assertTrue(true); }
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
static void foo() {
Ar<String> a = Stri<caret>ng[]::new;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
static void foo() {
Ar<String> a = Str<caret>ing[][]::new;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
public void test() {
Object i = null;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
static void foo() {
Cln j = i<caret>nt[]::clone;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
public class MyTest {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.List;
import java.util.stream.Stream;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.Comparator;
class MyTest {
void setComparator(Comparator<?> comparator) {}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
public class MyTest {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.*;
public class MyTest {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.*;
public class MyTest<T> {
@@ -0,0 +1,6 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
class Test {
boolean result = Arrays.asList("a", "a").stream().allMatch(new <caret>HashSet<>()::add);
}
@@ -0,0 +1,9 @@
// "Replace method reference with lambda|->Keep possible side effects inside lambda" "true-preview"
import java.util.*;
class Test {
{
List<String> strings = Arrays.asList("a", "a");
System.out.println(strings.stream().allMatch(new <caret>HashSet<>()::add));
}
}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Test {
void test(){
class Local(){}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.*;
public class MyTest {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
class Test
{
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class Foo {
public static class Bar {}
}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class Test1 {
static class Inner {
}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
MyTest() {}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest<X> {
MyTest(X x) {}
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
interface I {
void m(Integer s);
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class MyTest {
static class Inner {
Inner(MyTest mt) {};
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class MyTest {
static class Inner {
Inner(MyTest outer) {};
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.IntConsumer;
public class Main {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.function.Function;
abstract class Result<V> {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
interface I {
void m(MyTest receiver);
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.Comparator;
class A {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
interface I { void foo(int i); }
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
import java.util.*;
class Bar {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
public class MyTest {
interface I {
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class MyTest {
static interface SAM {
void m(Integer i);
@@ -1,3 +1,4 @@
// "Replace method reference with lambda" "true-preview"
class Test<T> {
static void foo() {}
}
@@ -1,169 +1,27 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.fixes.style;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.testFramework.IdeaTestUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.IGQuickFixesTestCase;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.ig.style.MethodRefCanBeReplacedWithLambdaInspection;
import org.jetbrains.annotations.NotNull;
public class MethodRefCanBeReplacedWithLambdaFixTest extends IGQuickFixesTestCase {
import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_21;
public class MethodRefCanBeReplacedWithLambdaFixTest extends LightQuickFixParameterizedTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
Sdk sdk = IdeaTestUtil.getMockJdk18();
WriteAction.runAndWait(() -> ProjectJdkTable.getInstance().addJdk(sdk, getTestRootDisposable()));
ModuleRootModificationUtil.setModuleSdk(getModule(), sdk);
myFixture.enableInspections(new MethodRefCanBeReplacedWithLambdaInspection());
myDefaultHint = InspectionGadgetsBundle.message("method.ref.can.be.replaced.with.lambda.quickfix");
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return JAVA_21;
}
@Override
protected String getRelativePath() {
return "style/methodRefs2lambda";
protected String getBasePath() {
return "/ig/com/siyeh/igfixes/style/methodRefs2lambda";
}
public void testRedundantCast() {
doTest();
@Override
protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() {
return new MethodRefCanBeReplacedWithLambdaInspection[]{new MethodRefCanBeReplacedWithLambdaInspection()};
}
public void testStaticMethodRef() {
doTest();
}
public void testThisRefs() {
doTest();
}
public void testSuperRefs() {
doTest();
}
public void testExprRefs() {
doTest();
}
public void testReceiver() {
doTest();
}
public void testNewRefs() {
doTest();
}
public void testNewRefsDefaultConstructor() {
doTest();
}
public void testNewRefsInnerClass() {
doTest();
}
public void testNewRefsStaticInnerClass() {
doTest();
}
public void testNewRefsInference() {
doTest(myDefaultHint);
}
public void testNewRefsInference1() {
doTest();
}
public void testAmbiguity() {
doTest();
}
public void testSubst() {
doTest();
}
public void testTypeElementOnTheLeft() {
doTest();
}
public void testNewDefaultConstructor() {
doTest();
}
public void testArrayConstructorRef() {
doTest();
}
public void testArrayConstructorRef2Dim() {
doTest();
}
public void testArrayMethodRef() {
doTest(myDefaultHint );
}
public void testArrayConstructorRefUniqueParamName() {
doTest();
}
public void testNameConflicts() {
doTest();
}
public void testIntroduceVariableForSideEffectQualifier() {
doTest(myDefaultHint + " (side effects)");
}
public void testIntroduceVariableForNewInQualifier() {
doTest(myDefaultHint + " (side effects)");
}
public void testCollapseToExpressionLambdaWhenCast() {
doTest();
}
public void testPreserveExpressionQualifier() {
doTest();
}
public void testNoUnderscoreInLambdaParameterName() {
doTest();
}
public void testNoCastWhereCaptureArgIsExpected() {
doTest();
}
public void testCaptureOnInvalidatedReference() {
doTest();
}
public void testCaptureOnInvalidatedReference1() {
doTest();
}
public void testSpecifyFormalParameterTypesWhenMethodReferenceWasExactAndTypeOfParameterIsUnknown() {
doTest();
}
public void testNewArrayMethodReferenceHasNoSideEffects() { doTest(); }
public void testExplicitTypeRequired() { doTest(); }
public void testNestedClassReference(){
doTest();
}
public void testLocalClassReference(){
doTest();
}
public void testEnsureNoConversionIsSuggestedWhenLambdaWithoutCantBeInferredAndFormalParametersAreNotDenotable() {
assertQuickfixNotAvailable();
}
public void testBrokenPrimitiveArray() {
doTest();
}
public void testLocalGenericClass() { doTest(); }
public void testInnerGenericClass() { doTest(); }
public void testInnerGenericClass2() { doTest(); }
}
@@ -419,7 +419,6 @@ invocations.to.be.inlined=Invocations to be inlined {0}
is.modified.in.loop.body={0} is modified in loop body
javadoc.for.abstracts=JavaDoc for abstracts
keep.original.signature=Keep Original Signature
lambda.to.reference.side.effect.warning.message=There are possible side effects found in method reference qualifier.\nIntroduce local variable?
local.variable.description=local variable {0}
pattern.variable.description=pattern variable {0}
local.will.be.hidden.renamed.description=Renamed field will hide {0}
@@ -660,7 +659,6 @@ selected.expression.introduces.pattern.variable=Selected expression introduces p
popup.title.choose.class.to.introduce.constant=Choose class to introduce constant
popup.title.choose.class.to.introduce.field=Choose class to introduce field
setter.method.found.for.the.field.0=Setter method found for the field {0}. \n{1} the setter as well?
side.effects.detected.title=Side Effects Detected
source.folder.0.has.package.prefix.1=Source folder {0} has package prefix ''{1}''\nPackage ''{2}'' cannot be created there.
static.initializer.description=static initializer of {0}
class.initializer.description={0, choice, 0#static|1#instance} initializer