mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] IDEA-284073 Enhance dfa: Support that Stream.toList() is unmodifiable
PR#1861 GitOrigin-RevId: ddddc2451708df8e11d00e059eafdb8674fa562b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0b5d6324c8
commit
0ded7bc2f5
@@ -12,6 +12,7 @@ import com.intellij.java.analysis.JavaAnalysisBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightElement;
|
||||
import com.intellij.psi.impl.source.PsiMethodImpl;
|
||||
@@ -64,6 +65,8 @@ public enum Mutability {
|
||||
public static final @NotNull String UNMODIFIABLE_VIEW_ANNOTATION = UNMODIFIABLE_VIEW.myAnnotation;
|
||||
private static final @NotNull CallMatcher STREAM_COLLECT = CallMatcher.instanceCall(
|
||||
CommonClassNames.JAVA_UTIL_STREAM_STREAM, "collect").parameterTypes("java.util.stream.Collector");
|
||||
private static final @NotNull CallMatcher STREAM_TO_LIST = CallMatcher.instanceCall(
|
||||
CommonClassNames.JAVA_UTIL_STREAM_STREAM, "toList").withLanguageLevelAtLeast(LanguageLevel.JDK_16);
|
||||
private static final @NotNull CallMatcher UNMODIFIABLE_COLLECTORS = CallMatcher.staticCall(
|
||||
CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, "toUnmodifiableList", "toUnmodifiableSet", "toUnmodifiableMap");
|
||||
private final @PropertyKey(resourceBundle = JavaAnalysisBundle.BUNDLE) String myResourceKey;
|
||||
@@ -187,6 +190,8 @@ public enum Mutability {
|
||||
if (STREAM_COLLECT.test(call)) {
|
||||
PsiExpression collector = call.getArgumentList().getExpressions()[0];
|
||||
newMutability = UNMODIFIABLE_COLLECTORS.matches(collector) ? UNMODIFIABLE : UNKNOWN;
|
||||
} else if (STREAM_TO_LIST.test(call)) {
|
||||
newMutability = UNMODIFIABLE;
|
||||
} else {
|
||||
PsiMethod method = call.resolveMethod();
|
||||
newMutability = method == null ? UNKNOWN : getMutability(method);
|
||||
|
||||
+4
@@ -28,6 +28,7 @@ import com.intellij.codeInspection.dataFlow.types.DfType;
|
||||
import com.intellij.codeInspection.dataFlow.types.DfTypes;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.RelationType;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -69,6 +70,8 @@ public class StreamChainInliner implements CallInliner {
|
||||
instanceCall(JAVA_UTIL_STREAM_STREAM, "reduce").parameterTypes("T", "java.util.function.BinaryOperator");
|
||||
private static final CallMatcher COLLECT_TERMINAL =
|
||||
instanceCall(JAVA_UTIL_STREAM_STREAM, "collect").parameterTypes("java.util.stream.Collector");
|
||||
private static final CallMatcher TO_LIST_TERMINAL = instanceCall(JAVA_UTIL_STREAM_STREAM, "toList")
|
||||
.withLanguageLevelAtLeast(LanguageLevel.JDK_16);
|
||||
private static final CallMatcher COLLECT3_TERMINAL =
|
||||
instanceCall(JAVA_UTIL_STREAM_STREAM, "collect").parameterTypes("java.util.function.Supplier",
|
||||
"java.util.function.BiConsumer", "java.util.function.BiConsumer");
|
||||
@@ -142,6 +145,7 @@ public class StreamChainInliner implements CallInliner {
|
||||
.register(TO_ARRAY_TERMINAL, call -> new ToArrayStep(call))
|
||||
.register(COLLECT3_TERMINAL, call -> new Collect3TerminalStep(call))
|
||||
.register(COLLECT_TERMINAL, call -> createTerminalFromCollector(call))
|
||||
.register(TO_LIST_TERMINAL, call -> new ToCollectionStep(call, null, true))
|
||||
.register(TWO_ARG_REDUCE, call -> new TwoArgReduceStep(call));
|
||||
|
||||
private static final Step NULL_TERMINAL_STEP = new Step(null, null, null) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package java.util.stream;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.Spliterator;
|
||||
|
||||
//mock
|
||||
class Stream<T> implements BaseStream<T, Stream<T>>{
|
||||
public native List<T> toList();
|
||||
|
||||
public native Iterator<T> iterator();
|
||||
|
||||
public native Spliterator<T> spliterator();
|
||||
|
||||
public native boolean isParallel();
|
||||
|
||||
public native Stream<T> sequential();
|
||||
|
||||
public native Stream<T> parallel();
|
||||
|
||||
public native Stream<T> unordered();
|
||||
|
||||
public native Stream<T> onClose(Runnable var1);
|
||||
|
||||
public native void close();
|
||||
}
|
||||
|
||||
public class MutabilityJdk16 {
|
||||
|
||||
private final List<Integer> list = new Stream<Integer>().toList();
|
||||
|
||||
void testFieldList(){
|
||||
list.<warning descr="Immutable object is modified">add</warning>(4);
|
||||
}
|
||||
|
||||
void testToList() {
|
||||
List<Integer> l = new Stream<Integer>()
|
||||
.toList();
|
||||
l.<warning descr="Immutable object is modified">add</warning>(4);
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,6 @@ public class DataFlowInspection16Test extends DataFlowInspectionTestCase {
|
||||
doTest();
|
||||
}
|
||||
public void testStaticFieldInAnonymous() { doTest(); }
|
||||
|
||||
public void testMutabilityJdk16() { doTest(); }
|
||||
}
|
||||
Reference in New Issue
Block a user