From 0f431159c9c4e93dc8a1bc9d4dac9701a11fc813 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 13 Jan 2022 16:54:33 +0700 Subject: [PATCH] [java-dfa] Properly process boxing of generic parameter in constructor Fixes IDEA-286477 Primitive type considered null in generic GitOrigin-RevId: f9e8a5eae5505511d84258b8a1bd67deafe8b8a3 --- .../dataFlow/java/ControlFlowAnalyzer.java | 6 +++++- .../fixture/BoxingInConstructorArguments.java | 17 +++++++++++++++++ .../codeInspection/DataFlowInspectionTest.java | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/BoxingInConstructorArguments.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java index b8ce4f6916f9..0ba5345edddb 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java @@ -2011,6 +2011,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { private @Nullable PsiMethod pushConstructorArguments(PsiConstructorCall call) { PsiExpressionList args = call.getArgumentList(); PsiMethod ctr = call.resolveConstructor(); + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + if (call instanceof PsiNewExpression) { + substitutor = call.resolveMethodGenerics().getSubstitutor(); + } if (args != null) { PsiExpression[] arguments = args.getExpressions(); PsiParameter[] parameters = ctr == null ? null : ctr.getParameterList().getParameters(); @@ -2018,7 +2022,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { PsiExpression argument = arguments[i]; argument.accept(this); if (parameters != null && i < parameters.length) { - generateBoxingUnboxingInstructionFor(argument, parameters[i].getType()); + generateBoxingUnboxingInstructionFor(argument, substitutor.substitute(parameters[i].getType())); } } foldVarArgs(call, parameters); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/BoxingInConstructorArguments.java b/java/java-tests/testData/inspection/dataFlow/fixture/BoxingInConstructorArguments.java new file mode 100644 index 000000000000..0d6473b5cb14 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/BoxingInConstructorArguments.java @@ -0,0 +1,17 @@ + +class Prop { + private final T defaultValue; + private final Key key; + + public Prop(Key key, T defaultValue) { + assert defaultValue != null; + this.key = key; + this.defaultValue = defaultValue; + } + + public static void main(String[] args) { + Prop prop = new Prop<>(Key.EXAMPLE, 1); + } +} + +enum Key {EXAMPLE} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java index f3d8544517cb..360fbee10be9 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -717,4 +717,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testStringBuilderLengthReturn() { doTest(); } public void testEqualsTwoFields() { doTest();} public void testPureMethodReadsMutableArray() { doTest(); } + public void testBoxingInConstructorArguments() { doTest(); } }