mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 05:51:25 +07:00
[java-inspections] TrivialFunctionalExpressionUsageInspection: more accurate side-effect handling
IDEA-355026 "Trivial usage of functional expression" breaks semantics if one argument updates the variable used in another GitOrigin-RevId: e3d9374ecc427d62cee0d821473e9119ae240fc5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
041de56103
commit
5905b6f62a
@@ -70,7 +70,7 @@ public final class TrivialFunctionalExpressionUsageInspection extends AbstractBa
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static void simplifyAllLambdas(@NotNull PsiElement context) {
|
||||
List<@NotNull Problem> problems = SyntaxTraverser.psiTraverser(context)
|
||||
.filter(PsiLambdaExpression.class)
|
||||
@@ -96,7 +96,7 @@ public final class TrivialFunctionalExpressionUsageInspection extends AbstractBa
|
||||
if (callParent instanceof PsiReturnStatement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
|
||||
if (statements.length == 1) {
|
||||
return statements[0] instanceof PsiReturnStatement && expression.isValueCompatible();
|
||||
@@ -145,6 +145,7 @@ public final class TrivialFunctionalExpressionUsageInspection extends AbstractBa
|
||||
call.getArgumentList().getExpressionCount() == method.getParameterList().getParametersCount() &&
|
||||
elementContainerPredicate.test(call);
|
||||
if (!suitableMethod) return null;
|
||||
//if (SideEffectChecker.definitelyChangesSemantics(call)) return null;
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interfaceType);
|
||||
if (method == interfaceMethod || interfaceMethod != null && MethodSignatureUtil.isSuperMethod(interfaceMethod, method)) {
|
||||
return new Problem(referenceNameElement, fix);
|
||||
@@ -192,12 +193,14 @@ public final class TrivialFunctionalExpressionUsageInspection extends AbstractBa
|
||||
|
||||
List<PsiStatement> statements = new ArrayList<>();
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(lambda.getProject());
|
||||
List<List<PsiExpression>> allSideEffects = ContainerUtil.map(arguments, SideEffectChecker::extractSideEffectExpressions);
|
||||
int lastSideEffectIndex = ContainerUtil.lastIndexOf(allSideEffects, se -> !se.isEmpty());
|
||||
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
PsiExpression argument = arguments[i];
|
||||
PsiParameter parameter = parameters[i];
|
||||
List<PsiExpression> sideEffects = SideEffectChecker.extractSideEffectExpressions(argument);
|
||||
if (!sideEffects.isEmpty()) {
|
||||
if (i <= lastSideEffectIndex) {
|
||||
boolean used = VariableAccessUtils.variableIsUsed(parameter, lambda.getBody());
|
||||
if (used) {
|
||||
String name = parameter.getName();
|
||||
@@ -262,7 +265,7 @@ public final class TrivialFunctionalExpressionUsageInspection extends AbstractBa
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void solveNameConflicts(PsiStatement[] statements, @NotNull PsiElement anchor, @NotNull PsiLambdaExpression lambda) {
|
||||
Predicate<PsiVariable> allowedVar = variable -> PsiTreeUtil.isAncestor(lambda, variable, true);
|
||||
Project project = anchor.getProject();
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Replace method call on lambda with lambda body" "true-preview"
|
||||
import java.util.function.BinaryOperator;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
int l = 1;
|
||||
int q = 2;
|
||||
System.out.println(l + " " + q);
|
||||
Integer i = q;
|
||||
q = l;
|
||||
l = i;
|
||||
System.out.println(l + " " + q);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Replace method call on lambda with lambda body" "true-preview"
|
||||
import java.util.function.IntBinaryOperator;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
int l = 1;
|
||||
int q = 2;
|
||||
System.out.println(l + " " + q);
|
||||
int i = q;
|
||||
q++;
|
||||
l = i;
|
||||
System.out.println(l + " " + q);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Replace method call on lambda with lambda body" "true-preview"
|
||||
import java.util.function.BinaryOperator;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
int l = 1;
|
||||
int q = 2;
|
||||
System.out.println(l + " " + q);
|
||||
l = ((BinaryOperator<Integer>) (i, _) -> i).<caret>apply(q, q = l);
|
||||
System.out.println(l + " " + q);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Replace method call on lambda with lambda body" "true-preview"
|
||||
import java.util.function.IntBinaryOperator;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
int l = 1;
|
||||
int q = 2;
|
||||
System.out.println(l + " " + q);
|
||||
l = ((IntBinaryOperator) (i, _) -> i).<caret>applyAsInt(q, q++);
|
||||
System.out.println(l + " " + q);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user