[java-analysis] Hard-code that Throwable.initCause is mutates_this

This allows contract inference for methods like AssertionError(Object) constructor.
Fixes IDEA-260003 A warning is shown when Optional.get is called even when Optional.isPresent is verified before

GitOrigin-RevId: 548008f5462b828e0346f089474182f59ec39bd1
This commit is contained in:
Tagir Valeev
2021-01-22 12:55:45 +00:00
committed by intellij-monorepo-bot
parent 13f648a693
commit c5c09c693a
5 changed files with 36 additions and 2 deletions
@@ -54,7 +54,7 @@ public class ClassDataIndexer implements VirtualFileGist.GistCalculator<Map<HMem
static final BinaryOperator<Equations> MERGER =
(eq1, eq2) -> eq1.equals(eq2) ? eq1 : new Equations(Collections.emptyList(), false);
private static final int VERSION = 14; // change when inference algorithm changes
private static final int VERSION = 15; // change when inference algorithm changes
private static final int VERSION_MODIFIER = HardCodedPurity.AGGRESSIVE_HARDCODED_PURITY ? 1 : 0;
private static final int FINAL_VERSION = VERSION * 2 + VERSION_MODIFIER;
private static final VirtualFileGist<Map<HMember, Equations>> ourGist = GistManager.getInstance().newVirtualFileGist(
@@ -118,6 +118,11 @@ class HardCodedPurity {
if (method.methodName.equals("next") && method.methodDesc.startsWith("()") && method.internalClassName.equals("java/util/Iterator")) {
return true;
}
if (method.methodName.equals("initCause") && method.methodDesc.equals("(Ljava/lang/Throwable;)Ljava/lang/Throwable;") &&
method.internalClassName.startsWith("java/")) {
// Throwable.initCause is overridable. For Java classes, we assume that its contract is fixed
return true;
}
return super.isThisChangingMethod(method);
}
@@ -245,6 +245,11 @@
<val name="pure" val="true"/>
</annotation>
</item>
<item name='java.lang.AssertionError AssertionError(java.lang.Object)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="pure" val="true"/>
</annotation>
</item>
<item name='java.lang.AssertionError AssertionError(java.lang.Object) 0'>
<annotation name='org.jetbrains.annotations.Nullable'/>
</item>
@@ -4018,6 +4023,9 @@
<annotation name='org.jetbrains.annotations.Nullable'/>
</item>
<item name='java.lang.Throwable java.lang.Throwable initCause(java.lang.Throwable)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="mutates" val="&quot;this&quot;"/>
</annotation>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='java.lang.Throwable void addSuppressed(java.lang.Throwable) 0'>
@@ -567,6 +567,11 @@
<val name="pure" val="true"/>
</annotation>
</item>
<item name='java.lang.invoke.MemberName boolean referenceKindIsConsistentWith(int)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="pure" val="true"/>
</annotation>
</item>
<item name='java.lang.invoke.MemberName boolean testAllFlags(int)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="pure" val="true"/>
@@ -1307,7 +1312,8 @@
</item>
<item name='java.lang.invoke.MethodHandleStatics java.lang.Error NYI()'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val="&quot;-&gt;fail&quot;"/>
<val name="value" val="&quot;-&gt;fail&quot;"/>
<val name="pure" val="true"/>
</annotation>
</item>
<item name='java.lang.invoke.MethodHandleStatics java.lang.Error uncaughtException(java.lang.Throwable)'>
@@ -1,4 +1,19 @@
<root>
<item name='java.rmi.RemoteException RemoteException()'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="pure" val="true"/>
</annotation>
</item>
<item name='java.rmi.RemoteException RemoteException(java.lang.String)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="pure" val="true"/>
</annotation>
</item>
<item name='java.rmi.RemoteException RemoteException(java.lang.String, java.lang.Throwable)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="pure" val="true"/>
</annotation>
</item>
<item name='java.rmi.RemoteException java.lang.Throwable getCause()'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="pure" val="true"/>