mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
[java-dfa] Simplify Mutability computation using external annotations
GitOrigin-RevId: 6570f36a8fa94ca14f4341875b5b980c7124641a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9d683df66a
commit
73943d0839
@@ -10,7 +10,6 @@ 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;
|
||||
@@ -20,7 +19,6 @@ import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.ClassUtils;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import one.util.streamex.StreamEx;
|
||||
@@ -72,12 +70,6 @@ public enum Mutability {
|
||||
|
||||
public static final @NotNull String UNMODIFIABLE_ANNOTATION = UNMODIFIABLE.myAnnotation;
|
||||
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;
|
||||
private final String myAnnotation;
|
||||
private final Key<CachedValue<PsiAnnotation>> myKey;
|
||||
@@ -199,18 +191,12 @@ public enum Mutability {
|
||||
Mutability mutability = UNMODIFIABLE;
|
||||
for (PsiExpression initializer : expressions) {
|
||||
Mutability newMutability = UNKNOWN;
|
||||
if (ClassUtils.isImmutable(initializer.getType())) {
|
||||
PsiType type = initializer.getType();
|
||||
if (ClassUtils.isImmutable(type) || (type != null && type.hasAnnotation(UNMODIFIABLE_ANNOTATION))) {
|
||||
newMutability = UNMODIFIABLE;
|
||||
} else if (initializer instanceof PsiMethodCallExpression call) {
|
||||
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);
|
||||
}
|
||||
PsiMethod method = call.resolveMethod();
|
||||
newMutability = method == null ? UNKNOWN : getMutability(method);
|
||||
}
|
||||
mutability = mutability.join(newMutability);
|
||||
if (!mutability.isUnmodifiable()) break;
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package <error descr="Package 'java.util.stream' exists in another module: java.base">java.util.stream</error>;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import java.util.List;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class MutabilityJdk21 {
|
||||
|
||||
private final List<Integer> list = Stream.of(1, 2, 3).toList();
|
||||
|
||||
void testFieldList(){
|
||||
list.<warning descr="Immutable object is modified">add</warning>(4);
|
||||
}
|
||||
|
||||
void testToList() {
|
||||
List<Integer> l = Stream.of(1, 2, 3)
|
||||
.toList();
|
||||
l.<warning descr="Immutable object is modified">add</warning>(4);
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,6 @@ public class DataFlowInspection16Test extends DataFlowInspectionTestCase {
|
||||
}
|
||||
public void testStaticFieldInAnonymous() { doTest(); }
|
||||
|
||||
public void testMutabilityJdk16() { doTest(); }
|
||||
|
||||
public void testAccessorNullityUnderDefaultQualifier() {
|
||||
addCheckerAnnotations(myFixture);
|
||||
doTest();
|
||||
|
||||
@@ -202,4 +202,7 @@ public class DataFlowInspection21Test extends DataFlowInspectionTestCase {
|
||||
public void testPassthroughGenericParameter() {
|
||||
doTestWith((dfi, cvi) -> dfi.TREAT_UNKNOWN_MEMBERS_AS_NULLABLE = true);
|
||||
}
|
||||
|
||||
public void testMutabilityJdk21() { doTest(); }
|
||||
|
||||
}
|
||||
@@ -1034,6 +1034,10 @@
|
||||
<item name='java.util.stream.Stream java.lang.Object[] toArray()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='java.util.stream.Stream java.util.List<T> toList()'>
|
||||
<annotation name='org.jetbrains.annotations.Unmodifiable'/>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='java.util.stream.Stream java.util.Optional<T> findAny()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user