mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] IDEA-371838 Convert SideEffectsMethodRefToLambdaFix to ModCommand
GitOrigin-RevId: 8e1fff8b05604adf5fe3e6dc853d8ac952b5a242
This commit is contained in:
committed by
intellij-monorepo-bot
parent
943fdcf538
commit
5fd8eb4a09
@@ -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)
|
||||
|
||||
+87
-78
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
class Test {
|
||||
{
|
||||
Runnable runnable = () -> new Runnable() {
|
||||
{
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println(this);
|
||||
}
|
||||
}.run();
|
||||
runnable.run();
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
static void m(Integer i) { assertTrue(true); }
|
||||
+1
@@ -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
@@ -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
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class Foo {
|
||||
public void test() {
|
||||
Object i = null;
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class Foo {
|
||||
static void foo() {
|
||||
Cln j = ints -> ints.clone();
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
public class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Optional;
|
||||
|
||||
class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Comparator;
|
||||
class MyTest {
|
||||
void setComparator(Comparator<?> comparator) {}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
public class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.*;
|
||||
|
||||
public class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.*;
|
||||
|
||||
public class MyTest<T> {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
+11
@@ -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
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda|->Keep possible side effects inside lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class Test {
|
||||
{
|
||||
Runnable runnable1 = new Runnable() {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class Test {
|
||||
void test(){
|
||||
class Local(){}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.*;
|
||||
|
||||
public class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
class Test
|
||||
{
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class Foo {
|
||||
public static class Bar {}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class Test1 {
|
||||
static class Inner {
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
MyTest() {}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
interface I {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest<X> {
|
||||
|
||||
MyTest(X x) {}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
interface I {
|
||||
void m(Integer s);
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class MyTest {
|
||||
static class Inner {
|
||||
Inner(MyTest mt) {};
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class MyTest {
|
||||
static class Inner {
|
||||
Inner(MyTest outer) {};
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
public class Main {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.Function;
|
||||
|
||||
abstract class Result<V> {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
interface I {
|
||||
void m(MyTest receiver);
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Comparator;
|
||||
|
||||
class A {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
class Test {
|
||||
{
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
interface I { void foo(int i); }
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
class Bar {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
interface I {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class MyTest {
|
||||
static interface SAM {
|
||||
void m(Integer i);
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class Test<T> {
|
||||
static void foo() {}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
static void m(Integer i) { assertTrue(true); }
|
||||
+1
@@ -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
@@ -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
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class Foo {
|
||||
public void test() {
|
||||
Object i = null;
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class Foo {
|
||||
static void foo() {
|
||||
Cln j = i<caret>nt[]::clone;
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
public class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Optional;
|
||||
|
||||
class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "false"
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
class InlineRef<S> {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Comparator;
|
||||
class MyTest {
|
||||
void setComparator(Comparator<?> comparator) {}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
public class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.*;
|
||||
|
||||
public class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.*;
|
||||
|
||||
public class MyTest<T> {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
+6
@@ -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);
|
||||
}
|
||||
+9
@@ -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
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class Test {
|
||||
{
|
||||
Runnable runnable = new Ru<caret>nnable() {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class Test {
|
||||
void test(){
|
||||
class Local(){}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.*;
|
||||
|
||||
public class MyTest {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
class Test
|
||||
{
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class Foo {
|
||||
public static class Bar {}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class Test1 {
|
||||
static class Inner {
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
MyTest() {}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
interface I {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest<X> {
|
||||
|
||||
MyTest(X x) {}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
interface I {
|
||||
void m(Integer s);
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class MyTest {
|
||||
static class Inner {
|
||||
Inner(MyTest mt) {};
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class MyTest {
|
||||
static class Inner {
|
||||
Inner(MyTest outer) {};
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
public class Main {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.function.Function;
|
||||
|
||||
abstract class Result<V> {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
interface I {
|
||||
void m(MyTest receiver);
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.Comparator;
|
||||
|
||||
class A {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
class Test {
|
||||
{
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
interface I { void foo(int i); }
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
import java.util.*;
|
||||
|
||||
class Bar {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
public class MyTest {
|
||||
|
||||
interface I {
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class MyTest {
|
||||
static interface SAM {
|
||||
void m(Integer i);
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// "Replace method reference with lambda" "true-preview"
|
||||
class Test<T> {
|
||||
static void foo() {}
|
||||
}
|
||||
+14
-156
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user