From 5495f1f9ea08efd97fc58656267d888913e77d3b Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 21 Oct 2020 15:06:59 +0700 Subject: [PATCH] [java-analysis] Do not mark parameter as UNMODIFIABLE_VIEW if the method mutability is inferred Fixes false-positive in RedundantUnmodifiableInspection GitOrigin-RevId: 82cd0651ea87f62066a8a299ba3d5b572d617ab0 --- .../codeInspection/dataFlow/Mutability.java | 19 +++++++++++-------- .../beforeArgumentOfPureMethod.java | 10 ++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeArgumentOfPureMethod.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/Mutability.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/Mutability.java index 825b160fa1c3..87336436e633 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/Mutability.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/Mutability.java @@ -126,14 +126,17 @@ public enum Mutability { PsiMethod method = ObjectUtils.tryCast(list.getParent(), PsiMethod.class); if (method != null) { int index = list.getParameterIndex((PsiParameter)owner); - MutationSignature signature = MutationSignature.fromMethod(method); - if (signature.mutatesArg(index)) { - return MUTABLE; - } else if (signature.preservesArg(index) && - PsiTreeUtil.findChildOfAnyType(method.getBody(), PsiLambdaExpression.class, PsiClass.class) == null) { - // If method preserves argument, it still may return a lambda which captures an argument and changes it - // TODO: more precise check (at least differentiate parameters which are captured by lambdas or not) - return UNMODIFIABLE_VIEW; + JavaMethodContractUtil.ContractInfo contractInfo = JavaMethodContractUtil.getContractInfo(method); + if (contractInfo.isExplicit()) { + MutationSignature signature = contractInfo.getMutationSignature(); + if (signature.mutatesArg(index)) { + return MUTABLE; + } else if (signature.preservesArg(index) && + PsiTreeUtil.findChildOfAnyType(method.getBody(), PsiLambdaExpression.class, PsiClass.class) == null) { + // If method preserves argument, it still may return a lambda which captures an argument and changes it + // TODO: more precise check (at least differentiate parameters which are captured by lambdas or not) + return UNMODIFIABLE_VIEW; + } } return UNKNOWN; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeArgumentOfPureMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeArgumentOfPureMethod.java new file mode 100644 index 000000000000..4733aaa7fbe8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeArgumentOfPureMethod.java @@ -0,0 +1,10 @@ +// "Fix all 'Redundant usage of unmodifiable collection wrappers' problems in file" "false" + +import java.util.*; + +class Main { + + static List test(List list) { + return Collections.unmodifiableList(list); + } +}