diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantStreamOptionalCallInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantStreamOptionalCallInspection.java index 7b43a6f9f974..f20539f0e61b 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantStreamOptionalCallInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantStreamOptionalCallInspection.java @@ -183,12 +183,12 @@ public class RedundantStreamOptionalCallInspection extends BaseJavaBatchLocalIns } if (expression instanceof PsiLambdaExpression) { PsiLambdaExpression lambda = (PsiLambdaExpression)expression; + if (LambdaUtil.isIdentityLambda(lambda)) return true; + if (!allowBoxUnbox) return false; PsiExpression body = LambdaUtil.extractSingleExpressionFromBody(lambda.getBody()); PsiParameter[] parameters = lambda.getParameterList().getParameters(); if (parameters.length != 1) return false; PsiParameter parameter = parameters[0]; - if (ExpressionUtils.isReferenceTo(body, parameter)) return true; - if (!allowBoxUnbox) return false; PsiMethodCallExpression call = tryCast(PsiUtil.skipParenthesizedExprDown(body), PsiMethodCallExpression.class); if (call == null) return false; PsiReferenceExpression methodExpression = call.getMethodExpression(); diff --git a/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java b/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java index ab7ebaedcf56..4059e45121ba 100644 --- a/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java @@ -410,13 +410,7 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns "valueOf", PsiType.BOOLEAN)) { return true; } - if (arg instanceof PsiLambdaExpression) { - PsiLambdaExpression lambda = (PsiLambdaExpression)arg; - PsiExpression body = LambdaUtil.extractSingleExpressionFromBody(lambda.getBody()); - PsiParameterList parameters = lambda.getParameterList(); - return parameters.getParametersCount() == 1 && ExpressionUtils.isReferenceTo(body, parameters.getParameters()[0]); - } - return false; + return arg instanceof PsiLambdaExpression && LambdaUtil.isIdentityLambda((PsiLambdaExpression)arg); } @Nullable diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 1658481927bb..d36b469e4351 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -931,6 +931,30 @@ public class LambdaUtil { return variable.getName() + " -> " + expression.getText(); } + /** + * Returns true if lambda has single parameter and its return value is the same as parameter. + * + *

+ * The lambdas like this are considered identity lambda: {@code x -> x}, {@code x -> {return x;}} + * {@code (String x) -> (x)}, etc.

+ * + *

+ * This method does not check the lambda type, also it does not check whether auto-(un)boxing occurs, + * so a lambda like {@code ((Predicate)b -> b)} is also identity lambda even though it performs + * auto-unboxing. + *

+ * + * @param lambda a lambda to check + * @return true if the supplied lambda is an identity lambda + */ + public static boolean isIdentityLambda(PsiLambdaExpression lambda) { + PsiParameterList parameters = lambda.getParameterList(); + if(parameters.getParametersCount() != 1) return false; + PsiExpression expression = PsiUtil.skipParenthesizedExprDown(extractSingleExpressionFromBody(lambda.getBody())); + return expression instanceof PsiReferenceExpression && + ((PsiReferenceExpression)expression).isReferenceTo(parameters.getParameters()[0]); + } + public static class TypeParamsChecker extends PsiTypeVisitor { private PsiMethod myMethod; private final PsiClass myClass;