Contract inference: avoid inference of "_ -> param1" contract when primitive conversion takes place

GitOrigin-RevId: 45d14c16892297858e33d6bf1dd4822a373577ff
This commit is contained in:
Tagir Valeev
2019-12-22 08:42:08 +00:00
committed by intellij-monorepo-bot
parent 1ddf0f9e38
commit a8e4cd8462
4 changed files with 26 additions and 4 deletions
@@ -352,12 +352,13 @@ public class TypeConstraints {
@Override
public boolean equals(Object obj) {
return obj == this || obj instanceof ExactClass && myClass.equals(((ExactClass)obj).myClass);
return obj == this || obj instanceof ExactClass &&
myClass.getManager().areElementsEquivalent(myClass, ((ExactClass)obj).myClass);
}
@Override
public int hashCode() {
return myClass.hashCode();
return Objects.hashCode(myClass.getQualifiedName());
}
@Override
@@ -209,7 +209,7 @@ class ContractInferenceInterpreter {
if (type == PARENTH_EXPRESSION) {
return visitExpression(states, findExpressionChild(myTree, expr));
}
if (type == TYPE_CAST_EXPRESSION) {
if (type == TYPE_CAST_EXPRESSION && !isPrimitiveCast(myTree, expr)) {
return visitExpression(states, findExpressionChild(myTree, expr));
}
@@ -22,6 +22,8 @@ import com.intellij.psi.impl.cache.RecordUtil;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.LightTreeUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.java.IKeywordElementType;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -61,12 +63,26 @@ public class JavaLightTreeUtil {
@Nullable
public static LighterASTNode skipParenthesesCastsDown(@NotNull LighterAST tree, @Nullable LighterASTNode node) {
while (node != null && (node.getTokenType() == PARENTH_EXPRESSION || node.getTokenType() == TYPE_CAST_EXPRESSION)) {
while (node != null) {
IElementType type = node.getTokenType();
if (type != PARENTH_EXPRESSION && type != TYPE_CAST_EXPRESSION) break;
if (type == TYPE_CAST_EXPRESSION && isPrimitiveCast(tree, node)) break;
node = findExpressionChild(tree, node);
}
return node;
}
public static boolean isPrimitiveCast(@NotNull LighterAST tree, @NotNull LighterASTNode node) {
LighterASTNode typeElement = LightTreeUtil.firstChildOfType(tree, node, TYPE);
if (typeElement != null) {
LighterASTNode item = ContainerUtil.getOnlyItem(tree.getChildren(typeElement));
if (item.getTokenType() instanceof IKeywordElementType) {
return true;
}
}
return false;
}
@Nullable
public static LighterASTNode skipParenthesesDown(@NotNull LighterAST tree, @Nullable LighterASTNode expression) {
while (expression != null && expression.getTokenType() == PARENTH_EXPRESSION) {
@@ -705,6 +705,11 @@ static String test(String a, String b) {
""")
assert c == ['_, null -> null', 'null, !null -> null']
}
void "test primitive cast ignored"() {
def c = inferContracts("""static int test(long x) {return (int)x;}""")
assert c == []
}
private String inferContract(String method) {
return assertOneElement(inferContracts(method))