From 538893bcd17efabdcfcc50a4e46d931f406acb48 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 19 Oct 2020 12:00:24 +0700 Subject: [PATCH] [java-dfa] Do not rely on class qualified name when checking for assignability/convertibility Qualified name is absent for local classes, so it doesn't work correctly if local classes are inherited. Also, as we already have PsiClass objects themselves, we can skip unnecessary resolve by qualified name. Finally, we can go further in isConvertibleFrom and inline isInheritorOrSelf. This allows to deduplicate areElementsEquivalent, which is supposed to be symmetrical, so extra work is avoided. Fixes IDEA-253169 Inheritors of local class cause false-positive 'ArrayStoreException' warning GitOrigin-RevId: cbadd6e6e853ae2310427dd977187b61cf1b5d5e --- .../codeInspection/dataFlow/TypeConstraints.java | 12 +++++------- .../dataFlow/fixture/ArrayStoreProblems.java | 6 ++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraints.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraints.java index 1456ed729ee1..a7d0507c83f0 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraints.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraints.java @@ -359,9 +359,7 @@ public final class TypeConstraints { public boolean isAssignableFrom(@NotNull Exact other) { if (equals(other) || other instanceof Unresolved) return true; if (other instanceof ExactClass) { - String name = myClass.getQualifiedName(); - if (name == null) return false; - return InheritanceUtil.isInheritor(((ExactClass)other).myClass, name); + return InheritanceUtil.isInheritorOrSelf(((ExactClass)other).myClass, myClass, true); } return false; } @@ -379,10 +377,10 @@ public final class TypeConstraints { if (myClass.isInterface() && otherClass.isInterface()) return true; if (myClass.isInterface() && !otherClass.hasModifierProperty(PsiModifier.FINAL)) return true; if (otherClass.isInterface() && !myClass.hasModifierProperty(PsiModifier.FINAL)) return true; - String otherName = otherClass.getQualifiedName(); - String myName = myClass.getQualifiedName(); - return otherName != null && InheritanceUtil.isInheritor(myClass, otherName) || - myName != null && InheritanceUtil.isInheritor(otherClass, myName); + PsiManager manager = myClass.getManager(); + return manager.areElementsEquivalent(myClass, otherClass) || + otherClass.isInheritor(myClass, true) || + myClass.isInheritor(otherClass, true); } return false; } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ArrayStoreProblems.java b/java/java-tests/testData/inspection/dataFlow/fixture/ArrayStoreProblems.java index cbbf3d9fcd8d..f7c7dbbb6995 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/ArrayStoreProblems.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ArrayStoreProblems.java @@ -2,6 +2,12 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull; class ArrayStoreProblems { + void testLocalClass() { + abstract class Foo {} + Foo[] data = new Foo[1]; + data[0] = new Foo() {}; + } + void test(String[] args, Integer[] args2) { Object[] arr = args; arr[0] = 123;