[java-dfa] Support JEP 455: IDEA-352186 dfa for primitives in patterns

GitOrigin-RevId: 2033b095f35f02222aa40f43d37e07b0019c4324
This commit is contained in:
Mikhail Pyltsin
2024-04-29 21:17:42 +00:00
committed by intellij-monorepo-bot
parent 0f5c405185
commit 8416740b8c
15 changed files with 2450 additions and 28 deletions
@@ -36,6 +36,7 @@ import com.intellij.codeInspection.dataFlow.types.DfTypes;
import com.intellij.codeInspection.dataFlow.value.*;
import com.intellij.codeInspection.dataFlow.value.DfaControlTransferValue.Trap;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.pom.java.JavaFeature;
import com.intellij.psi.*;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.impl.source.tree.java.PsiEmptyExpressionImpl;
@@ -1182,7 +1183,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
@NotNull DfaVariableValue patternDfaVar,
@Nullable DfaAnchor instanceofAnchor) {
if (sourcePattern == innerPattern || !JavaPsiPatternUtil.isUnconditionalForType(innerPattern, checkType)) {
addPatternTypeTest(innerPattern, instanceofAnchor, endPatternOffset, patternDfaVar);
addPatternTypeTest(innerPattern, instanceofAnchor, endPatternOffset, patternDfaVar, checkType);
}
else {
addInstruction(new SimpleAssignmentInstruction(null, patternDfaVar));
@@ -1192,13 +1193,12 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
private void addPatternTypeTest(@NotNull PsiPattern pattern,
@Nullable DfaAnchor instanceofAnchor,
@NotNull DeferredOffset endPatternOffset,
@NotNull DfaVariableValue patternDfaVar) {
@NotNull DfaVariableValue patternDfaVar,
@NotNull PsiType checkType) {
DeferredOffset condGotoOffset;
addInstruction(new DupInstruction());
addInstruction(
new PushValueInstruction(DfTypes.typedObject(JavaPsiPatternUtil.getPatternType(pattern), Nullability.NOT_NULL)));
addInstruction(new InstanceofInstruction(instanceofAnchor, false));
PsiType patternType = JavaPsiPatternUtil.getPatternType(pattern);
generateInstanceOfInstructions(pattern, instanceofAnchor, checkType, patternType);
condGotoOffset = new DeferredOffset();
addInstruction(new ConditionalGotoInstruction(condGotoOffset, DfTypes.TRUE));
@@ -1211,6 +1211,163 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
condGotoOffset.setOffset(assignmentInstr.getIndex());
}
private void generateInstanceOfInstructions(@NotNull PsiElement context,
@Nullable DfaAnchor instanceofAnchor,
@NotNull PsiType checkType,
@Nullable PsiType patternType) {
if (patternType == null ||
(!PsiUtil.isAvailable(JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS, context) &&
(checkType instanceof PsiPrimitiveType || patternType instanceof PsiPrimitiveType)) ||
((checkType instanceof PsiPrimitiveType || patternType instanceof PsiPrimitiveType) &&
!TypeConversionUtil.areTypesConvertible(checkType, patternType))) {
addInstruction(new PopInstruction());
pushUnknown();
return;
}
if ((checkType instanceof PsiPrimitiveType) &&
patternType instanceof PsiPrimitiveType) {
if (checkType.equals(patternType) ||
JavaPsiPatternUtil.isExactPrimitiveWideningConversion(checkType, patternType)) {
addInstruction(new PopInstruction());
addInstruction(new PushValueInstruction(DfTypes.booleanValue(true)));
if (instanceofAnchor != null) {
addInstruction(new ResultOfInstruction(instanceofAnchor));
}
}
else {
generateExactTestingConversion(context, checkType, patternType, instanceofAnchor);
}
}
else if (checkType instanceof PsiPrimitiveType) {
PsiClassType boxedType = ((PsiPrimitiveType)checkType).getBoxedType(context);
generateBoxingUnboxingInstructionFor(context, checkType, boxedType, false);
addInstruction(new PushValueInstruction(DfTypes.typedObject(patternType, Nullability.NOT_NULL)));
addInstruction(new InstanceofInstruction(instanceofAnchor, false));
}
else if (patternType instanceof PsiPrimitiveType) {
PsiPrimitiveType unboxedCheckedType = PsiPrimitiveType.getUnboxedType(checkType);
if (unboxedCheckedType != null) {
boolean isWideningConversion = JavaPsiPatternUtil.isExactPrimitiveWideningConversion(unboxedCheckedType, patternType) ||
unboxedCheckedType.equals(patternType);
if (!isWideningConversion) {
addInstruction(new DupInstruction());
}
addInstruction(new PushValueInstruction(DfTypes.NULL));
addInstruction(new BooleanBinaryInstruction(RelationType.NE, false,
isWideningConversion ? instanceofAnchor : null));
if (!isWideningConversion) {
CFGBuilder builder = new CFGBuilder(this) //checkValue resultNotNull
.push(DfTypes.booleanValue(false)) //checkValue resultNotNull false
.ifCondition(RelationType.EQ) //checkValue
.pop() //
.push(DfTypes.booleanValue(false)) //false
.elseBranch(); //checkValue
generateBoxingUnboxingInstructionFor(context, checkType, unboxedCheckedType, false);
generateInstanceOfInstructions(context, null, unboxedCheckedType, patternType);
builder
.end();
if (instanceofAnchor != null) {
addInstruction(new ResultOfInstruction(instanceofAnchor));
}
}
}
else {
PsiClassType boxedType = ((PsiPrimitiveType)patternType).getBoxedType(context);
addInstruction(new PushValueInstruction(DfTypes.typedObject(boxedType, Nullability.NOT_NULL)));
addInstruction(new InstanceofInstruction(instanceofAnchor, false));
}
}
else {
addInstruction(new PushValueInstruction(DfTypes.typedObject(patternType, Nullability.NOT_NULL)));
addInstruction(new InstanceofInstruction(instanceofAnchor, false));
}
}
private void generateExactTestingConversion(@NotNull PsiElement context,
@NotNull PsiType checkType,
@NotNull PsiType patternType,
@Nullable DfaAnchor instanceofAnchor) {
PsiType exactlyPromotedType = JavaPsiPatternUtil.getExactlyPromotedType(context, checkType, patternType);
boolean checkTypeIsDouble = checkType.equals(PsiTypes.doubleType());
boolean checkTypeIsFloat = checkType.equals(PsiTypes.floatType());
boolean checkTypeIsLong = checkType.equals(PsiTypes.longType());
if (exactlyPromotedType.equalsToText("java.math.BigDecimal")) {
//there is no need to use BigDecimal explicitly, because
//there is some further simplification (see java.lang.runtime.ExactConversionsSupport)
if (checkTypeIsLong) {
exactlyPromotedType = PsiTypes.longType();
}
else if (checkTypeIsFloat) {
exactlyPromotedType = PsiTypes.floatType();
}
else {
exactlyPromotedType = PsiTypes.doubleType();
}
}
CFGBuilder builder = new CFGBuilder(this);
boolean generateOr = false;
boolean generateAnd = false;
if (checkTypeIsFloat || checkTypeIsDouble) {
if (patternType.equals(PsiTypes.floatType()) ||
patternType.equals(PsiTypes.doubleType())) {
generateOr = true;
builder //stack: checkValue
.dup() //checkValue checkValue
.dup() //checkValue checkValue checkValue
.compare(RelationType.EQ); //checkValue isNotNun
addInstruction(new NotInstruction(null)); //checkValue isNun
builder.swap(); //isNun checkValue
}
else {
generateAnd = true;
PsiClassType boxedType = checkTypeIsFloat
? PsiTypes.floatType().getBoxedType(context)
: PsiTypes.doubleType().getBoxedType(context);
builder //stack: checkValue
.dup(); // checkValue checkValue
generateBoxingUnboxingInstructionFor(context, checkType, boxedType, false); //checkValue ReferenceOfCheckValue
builder.push(checkTypeIsFloat
? DfTypes.floatValue(-0.0f)
: DfTypes.doubleValue(-0.0f)) ;// checkValue ReferenceOfCheckValue -0.0
generateBoxingUnboxingInstructionFor(context, PsiTypes.doubleType(), boxedType, false); //checkValue ReferenceOfCheckValue ReferenceNegativeZero
addInstruction(new BooleanBinaryInstruction(RelationType.NE, true, null)); //checkValue IsNotMinusZero
builder.swap(); //IsNotMinusZero checkValue
if (patternType.equals(PsiTypes.longType())) {
builder.dup()//IsNotMinusZero checkValue checkValue
//see com.google.common.math.DoubleMath.MAX_LONG_AS_DOUBLE_PLUS_ONE for explanation
.push(checkTypeIsFloat
? DfTypes.floatValue(0x1p63F)
: DfTypes.doubleValue(0x1p63)) //IsNotMinusZero checkValue checkValue maxLong
.compare(RelationType.NE) //IsNotMinusZero checkValue notMax
.splice(3, 1, 0, 2); //checkValue IsNotMinusZero notMax
addInstruction(new BooleanAndOrInstruction(false, null));//checkValue result
builder.swap(); //result checkValue
}
}
} else if(checkTypeIsLong &&
(patternType.equals(PsiTypes.floatType()) ||
patternType.equals(PsiTypes.doubleType()))){
generateAnd = true;
builder //checkValue
.dup() //checkValue checkValue
.push(DfTypes.longValue(Long.MAX_VALUE)) //checkValue checkValue Max_long
.compare(RelationType.NE) //checkValue NotMaxLong
.swap(); //NotMaxLong checkValue
}
builder.dup(); //something checkValue checkValue
generateBoxingUnboxingInstructionFor(context, checkType, exactlyPromotedType, false); //something checkValue casted
builder.swap(); //something casted checkValue
generateBoxingUnboxingInstructionFor(context, checkType, patternType, false);
generateBoxingUnboxingInstructionFor(context, patternType, exactlyPromotedType, false);
addInstruction(new BooleanBinaryInstruction(RelationType.EQ, false, generateOr || generateAnd ? null : instanceofAnchor));
if (generateOr) {
addInstruction(new BooleanAndOrInstruction(true, instanceofAnchor));
}
if (generateAnd) {
addInstruction(new BooleanAndOrInstruction(false, instanceofAnchor));
}
}
@Override
public void visitMethodReferenceExpression(@NotNull PsiMethodReferenceExpression expression) {
startElement(expression);
@@ -1757,7 +1914,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
generateBoxingUnboxingInstructionFor(expression, expression.getType(), expectedType, false);
}
void generateBoxingUnboxingInstructionFor(@NotNull PsiExpression context, PsiType actualType, PsiType expectedType, boolean explicit) {
void generateBoxingUnboxingInstructionFor(@NotNull PsiElement context, PsiType actualType, PsiType expectedType, boolean explicit) {
if (PsiTypes.voidType().equals(expectedType)) return;
if (TypeConversionUtil.isPrimitiveAndNotNull(expectedType) &&
@@ -1782,7 +1939,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
TypeConversionUtil.isPrimitiveAndNotNull(expectedType) &&
TypeConversionUtil.isNumericType(actualType) &&
TypeConversionUtil.isNumericType(expectedType)) {
DfaAnchor anchor = explicit ? new JavaExpressionAnchor(context) : null;
DfaAnchor anchor = (explicit && context instanceof PsiExpression psiExpression) ? new JavaExpressionAnchor(psiExpression) : null;
addInstruction(new PrimitiveConversionInstruction((PsiPrimitiveType)expectedType, anchor));
}
}
@@ -1874,11 +2031,11 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
PsiTypeElement checkType = InstanceOfUtils.findCheckTypeElement(expression);
CFGBuilder builder = new CFGBuilder(this);
if (pattern == null) {
if (checkType == null) {
if (checkType == null || operandType == null) {
pushUnknown();
}
else {
buildSimpleInstanceof(builder, expression, operand, checkType);
buildSimpleInstanceof(builder, expression, operand, operandType, checkType);
}
}
else if (operandType != null) {
@@ -1895,15 +2052,15 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
finishElement(expression);
}
private static void buildSimpleInstanceof(CFGBuilder builder,
PsiInstanceOfExpression expression,
PsiExpression operand,
PsiTypeElement checkType) {
private void buildSimpleInstanceof(@NotNull CFGBuilder builder,
@NotNull PsiInstanceOfExpression expression,
@NotNull PsiExpression operand,
@NotNull PsiType operandType,
@NotNull PsiTypeElement checkType) {
PsiType type = checkType.getType();
builder
.pushExpression(operand)
.push(DfTypes.typedObject(type, Nullability.NOT_NULL))
.isInstance(expression);
.pushExpression(operand);
generateInstanceOfInstructions(expression, new JavaExpressionAnchor(expression), operandType, type);
}
void addMethodThrows(@Nullable PsiMember methodOrClass) {
@@ -177,7 +177,8 @@ public final class PatternVariableCanBeUsedInspection extends AbstractBaseJavaLo
PsiExpression operand = cast.getOperand();
if (operand == null) return;
PsiType castType = cast.getCastType().getType();
if (castType instanceof PsiPrimitiveType) return;
if (castType instanceof PsiPrimitiveType &&
!JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS.isSufficient(PsiUtil.getLanguageLevel(operand))) return;
if (!variable.getType().equals(castType)) return;
PsiType operandType = operand.getType();
if (operandType == null || castType.isAssignableFrom(operandType)) return;
@@ -431,7 +432,8 @@ public final class PatternVariableCanBeUsedInspection extends AbstractBaseJavaLo
PsiExpression operand = expression.getOperand();
if (operand == null) return null;
PsiType castType = castTypeElement.getType();
if (castType instanceof PsiPrimitiveType) return null;
if (castType instanceof PsiPrimitiveType &&
!JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS.isSufficient(PsiUtil.getLanguageLevel(operand))) return null;
PsiType operandType = operand.getType();
if (operandType == null || castType.isAssignableFrom(operandType)) return null;
PsiInstanceOfExpression instanceOf = InstanceOfUtils.findPatternCandidate(expression, null);
@@ -321,13 +321,17 @@ public final class ConstantValueInspection extends AbstractBaseJavaLocalInspecti
}
if (expression instanceof PsiInstanceOfExpression instanceOf) {
PsiType type = instanceOf.getOperand().getType();
if (type == null || !TypeConstraints.instanceOf(type).isResolved()) return true;
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(instanceOf);
if (type == null ||
(!TypeConstraints.instanceOf(type).isResolved() &&
(!JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS.isSufficient(languageLevel) ||
!(type instanceof PsiPrimitiveType)))) {
return true;
}
PsiPattern pattern = instanceOf.getPattern();
if (pattern instanceof PsiTypeTestPattern typeTestPattern && typeTestPattern.getPatternVariable() != null) {
PsiTypeElement checkType = typeTestPattern.getCheckType();
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(instanceOf);
if (checkType != null && checkType.getType().isAssignableFrom(type) &&
//see com.intellij.codeInsight.daemon.impl.analysis.HighlightVisitorImpl.visitInstanceOfExpression
!JavaFeature.PATTERN_GUARDS_AND_RECORD_PATTERNS.isSufficient(languageLevel)) {
// Reported as compilation error
return true;
@@ -4,6 +4,7 @@ package com.intellij.psi.util;
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.pom.java.JavaFeature;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
@@ -20,6 +21,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public final class JavaPsiPatternUtil {
private static final String JAVA_MATH_BIG_DECIMAL = "java.math.BigDecimal";
/**
* @param expression expression to search pattern variables in
* @return list of pattern variables declared within an expression that could be visible outside of given expression.
@@ -204,11 +208,109 @@ public final class JavaPsiPatternUtil {
public static boolean isUnconditionalForType(@Nullable PsiCaseLabelElement pattern, @NotNull PsiType type, boolean forDomination) {
PsiPrimaryPattern unconditionalPattern = findUnconditionalPattern(pattern);
if (unconditionalPattern == null) return false;
PsiType patternType = getPatternType(unconditionalPattern);
if (unconditionalPattern instanceof PsiDeconstructionPattern) {
return forDomination && dominates(getPatternType(unconditionalPattern), type);
return forDomination && dominates(patternType, type);
}
else if (unconditionalPattern instanceof PsiTypeTestPattern || unconditionalPattern instanceof PsiUnnamedPattern) {
return dominates(getPatternType(unconditionalPattern), type);
else if ((unconditionalPattern instanceof PsiTypeTestPattern ||
unconditionalPattern instanceof PsiUnnamedPattern) &&
JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS.isSufficient(PsiUtil.getLanguageLevel(pattern))) {
if (type instanceof PsiPrimitiveType || patternType instanceof PsiPrimitiveType) {
if (type.equals(patternType)) return true;
if (type instanceof PsiPrimitiveType && patternType instanceof PsiPrimitiveType) {
return isExactPrimitiveWideningConversion(type, patternType);
}
else if (!(type instanceof PsiPrimitiveType)) {
return false;
}
else {
PsiClassType boxedType = ((PsiPrimitiveType)type).getBoxedType(pattern);
return dominates(boxedType, type);
}
}
else {
return dominates(patternType, type);
}
}
return false;
}
/**
* Returns the promoted type for a given context, type, and pattern type, according to 5.7.1
*
* @param context the context element
* @param type the type to be promoted
* @param patternType the pattern type to compare with
* @return the promoted type, or the original type if no promotion is necessary
*/
@NotNull
public static PsiType getExactlyPromotedType(@NotNull PsiElement context, @NotNull PsiType type, @NotNull PsiType patternType) {
if (type.equals(patternType)) return type;
if ((type.equals(PsiTypes.byteType()) ||
type.equals(PsiTypes.shortType())) &&
patternType.equals(PsiTypes.charType())) {
return PsiTypes.intType();
}
else if ((patternType.equals(PsiTypes.byteType()) ||
patternType.equals(PsiTypes.shortType())) &&
type.equals(PsiTypes.charType())) {
return PsiTypes.intType();
}
else if ((type.equals(PsiTypes.intType()) &&
patternType.equals(PsiTypes.floatType())) ||
(type.equals(PsiTypes.floatType()) &&
patternType.equals(PsiTypes.intType()))) {
return PsiTypes.doubleType();
}
else if ((type.equals(PsiTypes.longType()) &&
patternType.equals(PsiTypes.floatType())) ||
(type.equals(PsiTypes.floatType()) &&
patternType.equals(PsiTypes.longType())) ||
(type.equals(PsiTypes.longType()) &&
patternType.equals(PsiTypes.doubleType())) ||
(type.equals(PsiTypes.doubleType()) &&
patternType.equals(PsiTypes.longType()))) {
return PsiType.getTypeByName(JAVA_MATH_BIG_DECIMAL, context.getProject(), context.getResolveScope());
}
else {
return TypeConversionUtil.isAssignable(patternType, type) ? patternType : type;
}
}
/**
* Checks if the given type is an exact primitive widening conversion of the pattern type according to 5.1.2
*
* @param type the type to check
* @param patternType the pattern type to compare with
* @return true if the given type is an exact primitive widening conversion of the pattern type, false otherwise
*/
public static boolean isExactPrimitiveWideningConversion(@NotNull PsiType type, @NotNull PsiType patternType) {
if (type.equals(PsiTypes.byteType())) {
return patternType.equals(PsiTypes.shortType()) ||
patternType.equals(PsiTypes.intType()) ||
patternType.equals(PsiTypes.longType()) ||
patternType.equals(PsiTypes.floatType()) ||
patternType.equals(PsiTypes.doubleType());
}
if (type.equals(PsiTypes.shortType())) {
return patternType.equals(PsiTypes.intType()) ||
patternType.equals(PsiTypes.longType()) ||
patternType.equals(PsiTypes.floatType()) ||
patternType.equals(PsiTypes.doubleType());
}
if (type.equals(PsiTypes.charType())) {
return patternType.equals(PsiTypes.intType()) ||
patternType.equals(PsiTypes.longType()) ||
patternType.equals(PsiTypes.floatType()) ||
patternType.equals(PsiTypes.doubleType());
}
if (type.equals(PsiTypes.intType())) {
return patternType.equals(PsiTypes.longType()) ||
patternType.equals(PsiTypes.doubleType());
}
if (type.equals(PsiTypes.floatType())) {
return patternType.equals(PsiTypes.doubleType());
}
return false;
}
@@ -40,7 +40,7 @@ class Bar extends Foo {
@Override
void test2(Point[] points) {
for (Point(<error descr="Incompatible types. Found: 'int', required: 'double'">int x</error>, <error descr="Incompatible types. Found: 'int', required: 'double'">int y</error>) : points) {}
for (<error descr="Pattern 'Point' is not exhaustive on 'Point'">Point(int x, int y)</error> : points) {}
}
@Override
@@ -0,0 +1,298 @@
package dfa;
public class InstanceofFromBoxedObjectToPrimitive {
public static void main(String[] args) {
System.out.println("testIntegerMin");
testIntegerMin();
System.out.println("testIntegerMax");
testIntegerMax();
System.out.println("testIntegerNull");
testIntegerNull();
System.out.println("testCharMin");
testCharMin();
System.out.println("testCharMax");
testCharMax();
System.out.println("testByteMin");
testByteMin();
System.out.println("testByteMax");
testByteMax();
System.out.println("testShortMin");
testShortMin();
System.out.println("testShortMax");
testShortMax();
System.out.println("testLongMin");
testLongMin();
System.out.println("testLongMax");
testLongMax();
System.out.println("testFloatMin");
testFloatMin();
System.out.println("testFloatMax");
testFloatMax();
System.out.println("testDoubleMin");
testDoubleMin();
System.out.println("testDoubleMax");
testDoubleMax();
System.out.println("testBooleanMin");
testBooleanMin();
System.out.println("testBooleanMax");
testBooleanMax();
}
private static void testBooleanMin() {
Boolean o = false;
if (<warning descr="Condition 'o instanceof boolean b' is always 'true'">o instanceof boolean b</warning>) { //true
System.out.println("boolean");
}
}
private static void testBooleanMax() {
Boolean o = true;
if (<warning descr="Condition 'o instanceof boolean b' is always 'true'">o instanceof boolean b</warning>) { //true
System.out.println("boolean");
}
}
private static void testDoubleMin() {
Double o = 0.0;
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testDoubleMax() {
Double o = Double.MAX_VALUE;
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testFloatMin() {
Float o = 0.0F;
if (<warning descr="Condition 'o instanceof float' is always 'true'">o instanceof float</warning>) { //true
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testFloatMax() {
Float o = Float.MAX_VALUE;
if (<warning descr="Condition 'o instanceof float' is always 'true'">o instanceof float</warning>) { //true
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testLongMin() {
Long o = 0l;
if (<warning descr="Condition 'o instanceof long' is always 'true'">o instanceof long</warning>) { //true
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'true'">o instanceof float</warning>) { //true
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testLongMax() {
Long o = Long.MAX_VALUE;
if (<warning descr="Condition 'o instanceof long' is always 'true'">o instanceof long</warning>) { //true
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) { //false
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'false'">o instanceof double</warning>) { //false
System.out.println("double");
}
}
private static void testShortMin() {
Short o = 0;
if (<warning descr="Condition 'o instanceof int i' is always 'true'">o instanceof int i</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof short' is always 'true'">o instanceof short</warning>) { //true
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'true'">o instanceof long</warning>) { //true
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'true'">o instanceof float</warning>) { //true
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testShortMax() {
Short o = Short.MAX_VALUE;
if (<warning descr="Condition 'o instanceof int i' is always 'true'">o instanceof int i</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof short' is always 'true'">o instanceof short</warning>) { //true
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'true'">o instanceof long</warning>) { //true
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'true'">o instanceof float</warning>) { //true
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testByteMin() {
Byte o = 0;
if (<warning descr="Condition 'o instanceof int' is always 'true'">o instanceof int</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof byte' is always 'true'">o instanceof byte</warning>) { //true
System.out.println("byte");
}
if (<warning descr="Condition 'o instanceof short' is always 'true'">o instanceof short</warning>) { //true
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'true'">o instanceof long</warning>) { //true
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'true'">o instanceof float</warning>) { //true
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testByteMax() {
Byte o = Byte.MAX_VALUE;
if (<warning descr="Condition 'o instanceof int' is always 'true'">o instanceof int</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof byte' is always 'true'">o instanceof byte</warning>) { //true
System.out.println("byte");
}
if (<warning descr="Condition 'o instanceof short' is always 'true'">o instanceof short</warning>) { //true
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'true'">o instanceof long</warning>) { //true
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'true'">o instanceof float</warning>) { //true
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
}
private static void testCharMin() {
Character o = 'c';
if (<warning descr="Condition 'o instanceof int t' is always 'true'">o instanceof int t</warning>) { //true
System.out.println("int" + t);
}
if (<warning descr="Condition 'o instanceof char t' is always 'true'">o instanceof char t</warning>) { //true
System.out.println("char" + t);
}
if (<warning descr="Condition 'o instanceof long t' is always 'true'">o instanceof long t</warning>) { //true
System.out.println("long" + t);
}
if (<warning descr="Condition 'o instanceof float t' is always 'true'">o instanceof float t</warning>) { //true
System.out.println("float" + t);
}
if (<warning descr="Condition 'o instanceof double t' is always 'true'">o instanceof double t</warning>) { //true
System.out.println("double" + t);
}
}
private static void testCharMax() {
Character o = Character.MAX_VALUE;
if (<warning descr="Condition 'o instanceof int t' is always 'true'">o instanceof int t</warning>) { //true
System.out.println("int" + t);
}
if (<warning descr="Condition 'o instanceof char t' is always 'true'">o instanceof char t</warning>) { //true
System.out.println("char" + t);
}
if (<warning descr="Condition 'o instanceof long t' is always 'true'">o instanceof long t</warning>) { //true
System.out.println("long" + t);
}
if (<warning descr="Condition 'o instanceof float t' is always 'true'">o instanceof float t</warning>) { //true
System.out.println("float" + t);
}
if (<warning descr="Condition 'o instanceof double t' is always 'true'">o instanceof double t</warning>) { //true
System.out.println("double" + t);
}
}
private static void testIntegerMin() {
Integer o = 0;
if (<warning descr="Condition 'o instanceof int' is always 'true'">o instanceof int</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof long' is always 'true'">o instanceof long</warning>) {//true
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'true'">o instanceof float</warning>) {//true
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) {//true
System.out.println("double");
}
}
private static void testIntegerMax() {
Integer o = Integer.MAX_VALUE;
if (<warning descr="Condition 'o instanceof int' is always 'true'">o instanceof int</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof long' is always 'true'">o instanceof long</warning>) {//true
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) {//false
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) {//true
System.out.println("double");
}
}
private static void testIntegerNull() {
Integer o = null;
if (<warning descr="Condition 'o instanceof int' is always 'false'">o instanceof int</warning>) { //false
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof long' is always 'false'">o instanceof long</warning>) {//false
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) {//false
System.out.println("float");
}
System.out.println("1");
if (<warning descr="Condition 'o instanceof double' is always 'false'">o instanceof double</warning>) {//false
System.out.println("double");
}
}
private static void testLongNull() {
Long o = null;
if (<warning descr="Condition 'o instanceof long' is always 'false'">o instanceof long</warning>) {//false
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) {//false
System.out.println("float");
}
System.out.println("1");
if (<warning descr="Condition 'o instanceof double' is always 'false'">o instanceof double</warning>) {//false
System.out.println("double");
}
System.out.println("2");
}
}
@@ -0,0 +1,420 @@
package dfa;
public class InstanceofFromObjectToPrimitive {
public static void main(String[] args) {
testSimple(0);
testObjectNull();
testObjectBoolean();
testNumberInt();
testObjectInt();
testObjectDouble();
testObjectBooleanPattern();
testNumberIntPattern();
testObjectIntPattern();
testObjectNullPattern();
testObjectDoublePattern();
testObjectRecord();
testNumberRecord();
testIntegerRecord();
testIntegerRecordNotNull();
testLongRecord();
testLongRecordNotNull();
}
private static void testObjectRecord() {
ObjectRecord o = new ObjectRecord(1);
if (o instanceof ObjectRecord(int a)) {
System.out.println("int");
}
if (o instanceof ObjectRecord(byte a)) {
System.out.println("byte");
}
if (o instanceof ObjectRecord(short a)) {
System.out.println("short");
}
if (o instanceof ObjectRecord(long a)) {
System.out.println("long");
}
if (o instanceof ObjectRecord(float a)) {
System.out.println("float");
}
if (o instanceof ObjectRecord(double a)) {
System.out.println("double");
}
}
private static void testNumberRecord() {
NumberRecord o = new NumberRecord(1);
if (o instanceof NumberRecord(int a)) {
System.out.println("int");
}
if (o instanceof NumberRecord(byte a)) {
System.out.println("byte");
}
if (o instanceof NumberRecord(short a)) {
System.out.println("short");
}
if (o instanceof NumberRecord(long a)) {
System.out.println("long");
}
if (o instanceof NumberRecord(float a)) {
System.out.println("float");
}
if (o instanceof NumberRecord(double a)) {
System.out.println("double");
}
}
private static void testIntegerRecord() {
IntegerRecord o = new IntegerRecord(1);
if (o instanceof IntegerRecord(int a)) {
System.out.println("int");
}
if (o instanceof IntegerRecord(long a)) {
System.out.println("long");
}
if (o instanceof IntegerRecord(float a)) {
System.out.println("float");
}
if (o instanceof IntegerRecord(double a)) {
System.out.println("double");
}
}
private static void testLongRecord() {
LongRecord o = new LongRecord(1L);
if (o instanceof LongRecord(long a)) {
System.out.println("long");
}
if (o instanceof LongRecord(float a)) {
System.out.println("float");
}
if (o instanceof LongRecord(double a)) {
System.out.println("double");
}
}
private static void testLongRecordNotNull() {
LongRecord o = new LongRecord(1L);
if (o.o() == null) {
return;
}
if (<warning descr="Condition 'o instanceof LongRecord(long a)' is always 'true'">o instanceof LongRecord(long a)</warning>) { //true
System.out.println("long");
}
if (o instanceof LongRecord(float a)) {
System.out.println("float");
}
if (o instanceof LongRecord(double a)) {
System.out.println("double");
}
}
private static void testIntegerRecordNotNull() {
IntegerRecord o = new IntegerRecord(1);
if (o.o() == null) {
return;
}
if (<warning descr="Condition 'o instanceof IntegerRecord(int a)' is always 'true'">o instanceof IntegerRecord(int a)</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof IntegerRecord(long a)' is always 'true'">o instanceof IntegerRecord(long a)</warning>) { //true
System.out.println("long");
}
if (o instanceof IntegerRecord(float a)) {
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof IntegerRecord(double a)' is always 'true'">o instanceof IntegerRecord(double a)</warning>) {//true
System.out.println("double");
}
}
record ObjectRecord(Object o) {
}
record NumberRecord(Number o) {
}
record IntegerRecord(Integer o) {
}
record LongRecord(Long o) {
}
private static void testSimple(Object i) {
if (i instanceof int) {
System.out.println(i);
}
}
public static void testObjectNull() {
Object o = null;
if (<warning descr="Condition 'o instanceof int' is always 'false'">o instanceof int</warning>) { //false
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof char' is always 'false'">o instanceof char</warning>) { //false
System.out.println("char");
}
if (<warning descr="Condition 'o instanceof byte' is always 'false'">o instanceof byte</warning>) { //false
System.out.println("byte");
}
if (<warning descr="Condition 'o instanceof short' is always 'false'">o instanceof short</warning>) { //false
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'false'">o instanceof long</warning>) { //false
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) { //false
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'false'">o instanceof double</warning>) { //false
System.out.println("double");
}
if (<warning descr="Condition 'o instanceof boolean' is always 'false'">o instanceof boolean</warning>) { //false
System.out.println("boolean");
}
}
public static void testObjectInt() {
Object o = 1;
if (<warning descr="Condition 'o instanceof int' is always 'true'">o instanceof int</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof char' is always 'false'">o instanceof char</warning>) { //false
System.out.println("char");
}
if (<warning descr="Condition 'o instanceof byte' is always 'false'">o instanceof byte</warning>) { //false
System.out.println("byte");
}
if (<warning descr="Condition 'o instanceof short' is always 'false'">o instanceof short</warning>) { //false
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'false'">o instanceof long</warning>) { //false
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) { //false
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'false'">o instanceof double</warning>) { //false
System.out.println("double");
}
if (<warning descr="Condition 'o instanceof boolean' is always 'false'">o instanceof boolean</warning>) { //false
System.out.println("boolean");
}
}
public static void testNumberInt() {
Number o = 1;
if (<warning descr="Condition 'o instanceof int' is always 'true'">o instanceof int</warning>) { //true
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof byte' is always 'false'">o instanceof byte</warning>) { //false
System.out.println("byte");
}
if (<warning descr="Condition 'o instanceof short' is always 'false'">o instanceof short</warning>) { //false
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'false'">o instanceof long</warning>) { //false
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) { //false
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'false'">o instanceof double</warning>) { //false
System.out.println("double");
}
}
public static void testObjectBoolean() {
Object o = true;
if (<warning descr="Condition 'o instanceof int' is always 'false'">o instanceof int</warning>) { //false
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof char' is always 'false'">o instanceof char</warning>) { //false
System.out.println("char");
}
if (<warning descr="Condition 'o instanceof byte' is always 'false'">o instanceof byte</warning>) { //false
System.out.println("byte");
}
if (<warning descr="Condition 'o instanceof short' is always 'false'">o instanceof short</warning>) { //false
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'false'">o instanceof long</warning>) { //false
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) { //false
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'false'">o instanceof double</warning>) { //false
System.out.println("double");
}
if (<warning descr="Condition 'o instanceof boolean' is always 'true'">o instanceof boolean</warning>) { //true
System.out.println("boolean");
}
}
public static void testObjectDouble() {
Object o = 1.0;
if (<warning descr="Condition 'o instanceof int' is always 'false'">o instanceof int</warning>) { //false
System.out.println("int");
}
if (<warning descr="Condition 'o instanceof char' is always 'false'">o instanceof char</warning>) { //false
System.out.println("char");
}
if (<warning descr="Condition 'o instanceof byte' is always 'false'">o instanceof byte</warning>) { //false
System.out.println("byte");
}
if (<warning descr="Condition 'o instanceof short' is always 'false'">o instanceof short</warning>) { //false
System.out.println("short");
}
if (<warning descr="Condition 'o instanceof long' is always 'false'">o instanceof long</warning>) { //false
System.out.println("long");
}
if (<warning descr="Condition 'o instanceof float' is always 'false'">o instanceof float</warning>) { //false
System.out.println("float");
}
if (<warning descr="Condition 'o instanceof double' is always 'true'">o instanceof double</warning>) { //true
System.out.println("double");
}
if (<warning descr="Condition 'o instanceof boolean' is always 'false'">o instanceof boolean</warning>) { //false
System.out.println("boolean");
}
}
public static void testObjectIntPattern() {
Object o = 1;
if (<warning descr="Condition 'o instanceof int t' is always 'true'">o instanceof int t</warning>) { //true
System.out.println("int" + t);
}
if (<warning descr="Condition 'o instanceof char t' is always 'false'">o instanceof char t</warning>) { //false
System.out.println("char" + t);
}
if (<warning descr="Condition 'o instanceof byte t' is always 'false'">o instanceof byte t</warning>) { //false
System.out.println("byte" + t);
}
if (<warning descr="Condition 'o instanceof short t' is always 'false'">o instanceof short t</warning>) { //false
System.out.println("short" + t);
}
if (<warning descr="Condition 'o instanceof long t' is always 'false'">o instanceof long t</warning>) { //false
System.out.println("long" + t);
}
if (<warning descr="Condition 'o instanceof float t' is always 'false'">o instanceof float t</warning>) { //false
System.out.println("float" + t);
}
if (<warning descr="Condition 'o instanceof double t' is always 'false'">o instanceof double t</warning>) { //false
System.out.println("double" + t);
}
if (<warning descr="Condition 'o instanceof boolean t' is always 'false'">o instanceof boolean t</warning>) { //false
System.out.println("boolean" + t);
}
}
public static void testObjectNullPattern() {
Object o = null;
if (<warning descr="Condition 'o instanceof int t' is always 'false'">o instanceof int t</warning>) { //false
System.out.println("int" + t);
}
if (<warning descr="Condition 'o instanceof char t' is always 'false'">o instanceof char t</warning>) { //false
System.out.println("char" + t);
}
if (<warning descr="Condition 'o instanceof byte t' is always 'false'">o instanceof byte t</warning>) { //false
System.out.println("byte" + t);
}
if (<warning descr="Condition 'o instanceof short t' is always 'false'">o instanceof short t</warning>) { //false
System.out.println("short" + t);
}
if (<warning descr="Condition 'o instanceof long t' is always 'false'">o instanceof long t</warning>) { //false
System.out.println("long" + t);
}
if (<warning descr="Condition 'o instanceof float t' is always 'false'">o instanceof float t</warning>) { //false
System.out.println("float" + t);
}
if (<warning descr="Condition 'o instanceof double t' is always 'false'">o instanceof double t</warning>) { //false
System.out.println("double" + t);
}
if (<warning descr="Condition 'o instanceof boolean t' is always 'false'">o instanceof boolean t</warning>) { //false
System.out.println("boolean" + t);
}
}
public static void testNumberIntPattern() {
Number o = 1;
if (<warning descr="Condition 'o instanceof int t' is always 'true'">o instanceof int t</warning>) { //true
System.out.println("int" + t);
}
if (<warning descr="Condition 'o instanceof byte t' is always 'false'">o instanceof byte t</warning>) { //false
System.out.println("byte" + t);
}
if (<warning descr="Condition 'o instanceof short t' is always 'false'">o instanceof short t</warning>) { //false
System.out.println("short" + t);
}
if (<warning descr="Condition 'o instanceof long t' is always 'false'">o instanceof long t</warning>) { //false
System.out.println("long" + t);
}
if (<warning descr="Condition 'o instanceof float t' is always 'false'">o instanceof float t</warning>) { //false
System.out.println("float" + t);
}
if (<warning descr="Condition 'o instanceof double t' is always 'false'">o instanceof double t</warning>) { //false
System.out.println("double" + t);
}
}
public static void testObjectBooleanPattern() {
Object o = true;
if (<warning descr="Condition 'o instanceof int t' is always 'false'">o instanceof int t</warning>) { //false
System.out.println("int" + t);
}
if (<warning descr="Condition 'o instanceof char t' is always 'false'">o instanceof char t</warning>) { //false
System.out.println("char" + t);
}
if (<warning descr="Condition 'o instanceof byte t' is always 'false'">o instanceof byte t</warning>) { //false
System.out.println("byte" + t);
}
if (<warning descr="Condition 'o instanceof short t' is always 'false'">o instanceof short t</warning>) { //false
System.out.println("short" + t);
}
if (<warning descr="Condition 'o instanceof long t' is always 'false'">o instanceof long t</warning>) { //false
System.out.println("long" + t);
}
if (<warning descr="Condition 'o instanceof float t' is always 'false'">o instanceof float t</warning>) { //false
System.out.println("float" + t);
}
if (<warning descr="Condition 'o instanceof double t' is always 'false'">o instanceof double t</warning>) { //false
System.out.println("double" + t);
}
if (<warning descr="Condition 'o instanceof boolean t' is always 'true'">o instanceof boolean t</warning>) { //true
System.out.println("boolean" + t);
}
}
public static void testObjectDoublePattern() {
Object o = 1.0;
if (<warning descr="Condition 'o instanceof int t' is always 'false'">o instanceof int t</warning>) { //false
System.out.println("int" + t);
}
if (<warning descr="Condition 'o instanceof char t' is always 'false'">o instanceof char t</warning>) { //false
System.out.println("char" + t);
}
if (<warning descr="Condition 'o instanceof byte t' is always 'false'">o instanceof byte t</warning>) { //false
System.out.println("byte" + t);
}
if (<warning descr="Condition 'o instanceof short t' is always 'false'">o instanceof short t</warning>) { //false
System.out.println("short" + t);
}
if (<warning descr="Condition 'o instanceof long t' is always 'false'">o instanceof long t</warning>) { //false
System.out.println("long" + t);
}
if (<warning descr="Condition 'o instanceof float t' is always 'false'">o instanceof float t</warning>) { //false
System.out.println("float" + t);
}
if (<warning descr="Condition 'o instanceof double t' is always 'true'">o instanceof double t</warning>) { //true
System.out.println("double" + t);
}
if (<warning descr="Condition 'o instanceof boolean t' is always 'false'">o instanceof boolean t</warning>) { //false
System.out.println("boolean" + t);
}
}
}
@@ -0,0 +1,169 @@
package dfa;
public class InstanceofFromPrimitiveToObject {
public static void main(String[] args) {
testSimple();
testInt();
testChar();
testByte();
testShort();
testLong();
testFloat();
testDouble();
testRecordInt();
testRecordLong();
testRecordFloat();
}
private static void testRecordInt() {
RecordInt a = new RecordInt(1);
if (<warning descr="Condition 'a instanceof RecordInt(Object o)' is always 'true'">a instanceof RecordInt(Object o)</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof RecordInt(Number o)' is always 'true'">a instanceof RecordInt(Number o)</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof RecordInt(Integer o)' is always 'true'">a instanceof RecordInt(Integer o)</warning>) { //true
System.out.println("Integer");
}
}
private static void testRecordLong() {
RecordLong a = new RecordLong(1);
if (<warning descr="Condition 'a instanceof RecordLong(Object o)' is always 'true'">a instanceof RecordLong(Object o)</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof RecordLong(Number o)' is always 'true'">a instanceof RecordLong(Number o)</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof RecordLong(Long o)' is always 'true'">a instanceof RecordLong(Long o)</warning>) { //true
System.out.println("Long");
}
}
private static void testRecordFloat() {
RecordFloat a = new RecordFloat(1);
if (<warning descr="Condition 'a instanceof RecordFloat(Object o)' is always 'true'">a instanceof RecordFloat(Object o)</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof RecordFloat(Number o)' is always 'true'">a instanceof RecordFloat(Number o)</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof RecordFloat(Float o)' is always 'true'">a instanceof RecordFloat(Float o)</warning>) { //true
System.out.println("Long");
}
}
record RecordInt(int a){}
record RecordLong(long a){}
record RecordFloat(float a){}
private static void testDouble() {
double a = Double.MAX_VALUE;
if (<warning descr="Condition 'a instanceof Object o' is always 'true'">a instanceof Object o</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof Number' is always 'true'">a instanceof Number</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof Double' is always 'true'">a instanceof Double</warning>) { //true
System.out.println("Double");
}
}
private static void testFloat() {
float a = 1;
if (<warning descr="Condition 'a instanceof Object o' is always 'true'">a instanceof Object o</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof Number' is always 'true'">a instanceof Number</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof Float' is always 'true'">a instanceof Float</warning>) { //true
System.out.println("Float");
}
}
private static void testLong() {
long a = 1;
if (<warning descr="Condition 'a instanceof Object o' is always 'true'">a instanceof Object o</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof Number' is always 'true'">a instanceof Number</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof Long' is always 'true'">a instanceof Long</warning>) { //true
System.out.println("Long");
}
}
private static void testShort() {
short a = 1;
if (<warning descr="Condition 'a instanceof Object o' is always 'true'">a instanceof Object o</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof Number' is always 'true'">a instanceof Number</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof Short' is always 'true'">a instanceof Short</warning>) { //true
System.out.println("Short");
}
}
private static void testByte() {
byte a = 1;
if (<warning descr="Condition 'a instanceof Object o' is always 'true'">a instanceof Object o</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof Number' is always 'true'">a instanceof Number</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof Byte' is always 'true'">a instanceof Byte</warning>) { //true
System.out.println("Byte");
}
}
private static void testChar() {
char a = Character.MAX_VALUE;
if (<warning descr="Condition 'a instanceof Object o' is always 'true'">a instanceof Object o</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof Character' is always 'true'">a instanceof Character</warning>) { //true
System.out.println("Character");
}
}
private static void testInt() {
int a = 1;
if (<warning descr="Condition 'a instanceof Object o' is always 'true'">a instanceof Object o</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof Number' is always 'true'">a instanceof Number</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof Integer' is always 'true'">a instanceof Integer</warning>) { //true
System.out.println("Integer");
}
}
private static void testSimple() {
int a = getInt();
if (<warning descr="Condition 'a instanceof Object o' is always 'true'">a instanceof Object o</warning>) { //true
System.out.println("Object");
}
if (<warning descr="Condition 'a instanceof Number' is always 'true'">a instanceof Number</warning>) { //true
System.out.println("Number");
}
if (<warning descr="Condition 'a instanceof Integer' is always 'true'">a instanceof Integer</warning>) { //true
System.out.println("Integer");
}
}
private static int getInt() {
return 0;
}
}
@@ -0,0 +1,38 @@
package dfa;
public class SwitchWithPrimitive {
public static void main(String[] args) {
testTestPattern(2L);
}
private static void testTestPattern(Long l2) {
long l = 0;
switch (l) {
case <warning descr="Switch label 'int i' is the only reachable in the whole switch">int i</warning> -> System.out.println("1");
case long i -> System.out.println("2");
}
switch (l) {
case <warning descr="Switch label '0L' is the only reachable in the whole switch">0L</warning> -> System.out.println("2");
case 1L -> System.out.println("2");
case 2L -> System.out.println("2");
case int i -> System.out.println("1");
case long i -> System.out.println("1");
}
switch (l) {
case 1L -> System.out.println("2");
case 2L -> System.out.println("2");
case <warning descr="Switch label 'long i' is the only reachable in the whole switch">long i</warning> -> System.out.println("1");
}
switch (l2) {
case 0L -> System.out.println("2");
case 1L -> System.out.println("2");
case 2L -> System.out.println("2");
case long i -> System.out.println("1");
}
switch (l2) {
case 1L -> System.out.println("2");
case 2L -> System.out.println("2");
case long i -> System.out.println("1");
}
}
}
@@ -0,0 +1,7 @@
// "Replace 's' with pattern variable" "true"
class X {
void test(float obj) {
if (obj instanceof int s) {
}
}
}
@@ -0,0 +1,8 @@
// "Replace 's' with pattern variable" "true"
class X {
void test(float obj) {
if (obj instanceof int) {
int <caret>s = (int)obj;
}
}
}
@@ -2,6 +2,7 @@
package com.intellij.java.codeInsight.daemon;
import com.intellij.JavaTestUtil;
import com.intellij.pom.java.JavaFeature;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
@@ -15,8 +16,7 @@ public class LightPrimitivePatternsHighlightingTest extends LightJavaCodeInsight
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
//todo change after new Java
return JAVA_X;
return new ProjectDescriptor(JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS.getMinimumLevel());
}
public void testRecordPrimitiveInstanceOfPattern() {
@@ -0,0 +1,41 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.pom.java.JavaFeature;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
public class DataFlowInspectionPrimitivesInPatternsTest extends DataFlowInspectionTestCase {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return new ProjectDescriptor(JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS.getMinimumLevel());
}
public void testInstanceofFromBoxedObjectToPrimitive() {
doTest();
}
public void testInstanceofFromObjectToPrimitive() {
doTest();
}
public void testInstanceofFromPrimitiveToObject() {
doTest();
}
public void testInstanceofFromPrimitiveToPrimitive() {
doTest();
}
public void testSwitchWithPrimitive() {
doTest();
}
@Override
protected String getTestDataPath() {
return JavaTestUtil.getJavaTestDataPath() + "/inspection/dataFlow/fixture/";
}
}
@@ -0,0 +1,35 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInspection;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.PatternVariableCanBeUsedInspection;
import com.intellij.pom.java.JavaFeature;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class PatternVariableCanBeUsedWithPrimitivesInspectionTest extends LightQuickFixParameterizedTestCase {
@Override
protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() {
PatternVariableCanBeUsedInspection inspection = new PatternVariableCanBeUsedInspection();
inspection.reportAlsoCastWithIntroducingNewVariable = true;
return new LocalInspectionTool[]{inspection};
}
@Override
protected LanguageLevel getLanguageLevel() {
return JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS.getMinimumLevel();
}
@Override
protected String getBasePath() {
return "/inspection/patternVariableCanBeUsedWithPrimitives";
}
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_X;
}
}