mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-dfa] IDEA-333294 Support Unit 5.8 assertInstanceOf in dataflow
GitOrigin-RevId: 5a772af8968128e8a95465d2ab5a42cb09006d3a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
477648476f
commit
d7160411f2
+2
-2
@@ -294,8 +294,8 @@ public class CFGBuilder {
|
||||
* @param anchor element to bind this instruction to
|
||||
* @return this builder
|
||||
*/
|
||||
public CFGBuilder isInstance(PsiMethodCallExpression anchor) {
|
||||
return add(new InstanceofInstruction(new JavaExpressionAnchor(anchor), true));
|
||||
public CFGBuilder isInstance(@Nullable PsiMethodCallExpression anchor) {
|
||||
return add(new InstanceofInstruction(anchor == null ? null : new JavaExpressionAnchor(anchor), true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -2560,6 +2560,6 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
new AssertJInliner(), new OptionalChainInliner(), new LambdaInliner(), new CollectionUpdateInliner(),
|
||||
new StreamChainInliner(), new MapUpdateInliner(), new AssumeInliner(), new ClassMethodsInliner(),
|
||||
new AssertAllInliner(), new BoxingInliner(), new SimpleMethodInliner(),
|
||||
new TransformInliner(), new EnumCompareInliner(), new IndexOfInliner()
|
||||
new TransformInliner(), new EnumCompareInliner(), new IndexOfInliner(), new AssertInstanceOfInliner()
|
||||
};
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection.dataFlow.java.inliner;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.java.CFGBuilder;
|
||||
import com.intellij.codeInspection.dataFlow.jvm.problems.ContractFailureProblem;
|
||||
import com.intellij.codeInspection.dataFlow.types.DfTypes;
|
||||
import com.intellij.codeInspection.dataFlow.value.RelationType;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.MethodCallUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class AssertInstanceOfInliner implements CallInliner {
|
||||
private static final CallMatcher ASSERT_INSTANCE_OF = CallMatcher.staticCall("org.junit.jupiter.api.Assertions", "assertInstanceOf");
|
||||
|
||||
@Override
|
||||
public boolean tryInlineCall(@NotNull CFGBuilder builder, @NotNull PsiMethodCallExpression call) {
|
||||
if (!ASSERT_INSTANCE_OF.matches(call)) return false;
|
||||
PsiExpression[] expressions = call.getArgumentList().getExpressions();
|
||||
if (expressions.length < 2 || expressions.length > 3) return false;
|
||||
PsiExpression wantedClass = expressions[0];
|
||||
PsiExpression objectToTest = expressions[1];
|
||||
builder.pushExpression(wantedClass)
|
||||
.pushExpression(objectToTest)
|
||||
.boxUnbox(objectToTest, PsiType.getJavaLangObject(call.getManager(), call.getResolveScope()))
|
||||
.splice(2, 0, 0, 1);
|
||||
if (expressions.length == 3) {
|
||||
builder.pushExpression(expressions[2]).pop();
|
||||
}
|
||||
builder.isInstance(null)
|
||||
.ensure(RelationType.EQ, DfTypes.TRUE, new ContractFailureProblem(call), CommonClassNames.JAVA_LANG_ASSERTION_ERROR)
|
||||
.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayInferPreciseType(@NotNull PsiExpression expression) {
|
||||
PsiParameter argument = MethodCallUtils.getParameterForArgument(expression);
|
||||
return argument != null && ASSERT_INSTANCE_OF.methodMatches((PsiMethod)argument.getDeclarationScope());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
|
||||
public class AssertInstanceOf {
|
||||
void test(Object str) {
|
||||
assertInstanceOf(String.class, str);
|
||||
if(<warning descr="Condition 'str instanceof String' is always 'true'">str instanceof String</warning>) {
|
||||
}
|
||||
<warning descr="The call to 'assertInstanceOf' always fails with an exception">assertInstanceOf</warning>(Number.class, str);
|
||||
}
|
||||
|
||||
void test2(Object obj) {
|
||||
int x;
|
||||
assertInstanceOf(String.class, obj, "hello " + (x = (obj instanceof Number ? 1 : 2)));
|
||||
if (<warning descr="Condition 'x == 2' is always 'true'">x == 2</warning>) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,4 +209,17 @@ public class HardcodedContractsTest extends DataFlowInspectionTestCase {
|
||||
}""");
|
||||
checkHighlighting();
|
||||
}
|
||||
|
||||
public void testAssertInstanceOf() {
|
||||
myFixture.addClass("""
|
||||
package org.junit.jupiter.api;
|
||||
import java.util.function.Supplier;
|
||||
public final class Assertions {
|
||||
public static native <T> T assertInstanceOf(Class<T> expectedType, Object actualValue);
|
||||
public static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue, String message);
|
||||
public static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue, Supplier<String> messageSupplier);
|
||||
}
|
||||
""");
|
||||
checkHighlighting();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user