diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java index 7b6bf72c4cce..3f65d087deef 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -7,6 +7,7 @@ import com.intellij.openapi.util.RecursionManager; import com.intellij.psi.*; import com.intellij.psi.impl.light.LightTypeParameter; import com.intellij.psi.impl.source.PsiClassReferenceType; +import com.intellij.psi.impl.source.PsiImmediateClassType; import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilCore; @@ -210,9 +211,8 @@ public final class PsiSubstitutorImpl implements PsiSubstitutor { return result; } PsiSubstitutor resultSubstitutor = processClass(aClass, resolveResult.getSubstitutor()); - PsiClassType result = JavaPsiFacade.getElementFactory(aClass.getProject()) - .createType(aClass, resultSubstitutor, classType.getLanguageLevel()); - return result.annotate(classType.getAnnotationProvider()); + return new PsiImmediateClassType(aClass, resultSubstitutor, classType.getLanguageLevel(), + classType.getAnnotationProvider(), classType.getPsiContext()); } private @NotNull PsiSubstitutor processClass(@NotNull PsiClass resolve, @NotNull PsiSubstitutor originalSubstitutor) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java index 3fa6473185eb..6fec7cc183dd 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java @@ -194,7 +194,7 @@ public class PsiClassReferenceType extends PsiClassType.Stub { PsiManager manager = reference.getManager(); PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject()); PsiSubstitutor rawSubstitutor = factory.createRawSubstitutor(aClass); - return new PsiImmediateClassType(aClass, rawSubstitutor, getLanguageLevel(), getAnnotationProvider()); + return new PsiImmediateClassType(aClass, rawSubstitutor, getLanguageLevel(), getAnnotationProvider(), null); } String qualifiedName = reference.getQualifiedName(); String name = reference.getReferenceName(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java index 171137b0cf21..39b5be8d56aa 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java @@ -29,6 +29,7 @@ public class PsiImmediateClassType extends PsiClassType.Stub { private final PsiClass myClass; private final PsiSubstitutor mySubstitutor; private final PsiManager myManager; + private final @Nullable PsiElement myPsiContext; private String myCanonicalText; private String myCanonicalTextAnnotated; private String myPresentableText; @@ -37,7 +38,7 @@ public class PsiImmediateClassType extends PsiClassType.Stub { private final ClassResolveResult myClassResolveResult = new ClassResolveResult() { private ClassResolveResult myCapturedResult = null; - + @Override public PsiClass getElement() { return myClass; @@ -52,7 +53,7 @@ public class PsiImmediateClassType extends PsiClassType.Stub { public ClassResolveResult resolveWithCapturedTopLevelWildcards() { ClassResolveResult result = myCapturedResult; if (result == null) { - myCapturedResult = result = ClassResolveResult.super.resolveWithCapturedTopLevelWildcards(); + myCapturedResult = result = ClassResolveResult.super.resolveWithCapturedTopLevelWildcards(); } return result; } @@ -95,21 +96,26 @@ public class PsiImmediateClassType extends PsiClassType.Stub { @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel level, PsiAnnotation @NotNull ... annotations) { - super(level, annotations); - myClass = aClass; - myManager = aClass.getManager(); - mySubstitutor = substitutor; - assert substitutor.isValid(); + this(aClass, substitutor, level, TypeAnnotationProvider.Static.create(annotations)); } public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel level, @NotNull TypeAnnotationProvider provider) { + this(aClass, substitutor, level, provider, null); + } + + public PsiImmediateClassType(@NotNull PsiClass aClass, + @NotNull PsiSubstitutor substitutor, + @Nullable LanguageLevel level, + @NotNull TypeAnnotationProvider provider, + @Nullable PsiElement context) { super(level, provider); myClass = aClass; myManager = aClass.getManager(); mySubstitutor = substitutor; + myPsiContext = context; substitutor.ensureValid(); } @@ -123,6 +129,11 @@ public class PsiImmediateClassType extends PsiClassType.Stub { return myClass.getName(); } + @Override + public @Nullable PsiElement getPsiContext() { + return myPsiContext; + } + @Override public int getParameterCount() { PsiTypeParameterList list = myClass.getTypeParameterList(); @@ -338,6 +349,6 @@ public class PsiImmediateClassType extends PsiClassType.Stub { @Override public @NotNull PsiClassType setLanguageLevel(@NotNull LanguageLevel level) { - return level.equals(myLanguageLevel) ? this : new PsiImmediateClassType(myClass, mySubstitutor, level, getAnnotationProvider()); + return level.equals(myLanguageLevel) ? this : new PsiImmediateClassType(myClass, mySubstitutor, level, getAnnotationProvider(), null); } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/JetBrainsNotNullByDefault.java b/java/java-tests/testData/inspection/dataFlow/fixture/JetBrainsNotNullByDefault.java index 9d085610eafe..83539b927e3b 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/JetBrainsNotNullByDefault.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/JetBrainsNotNullByDefault.java @@ -1,5 +1,46 @@ import org.jetbrains.annotations.*; import java.util.List; +import java.util.Random; + +@NotNullByDefault +class FromDemo { + native T get(); + + public void test() { + Object o = new FromDemo().get(); + if (o == null) { + System.out.println("1"); + } + } + + native T get2(); + + public void test2() { + Object o = new FromDemo().get2(); + if (o == null) { + System.out.println("1"); + } + } + + T oneOfTwo(T t1, T t2) { + return new Random().nextBoolean() ? t1 : t2; + } + + public void test(@Nullable Integer t1, @Nullable Integer t2) { + Integer o = new FromDemo().oneOfTwo(t1, t2); + // TODO: should not warn + if (o == null) { + System.out.println("1"); + } + } + + public void test2(Object t1, Object t2) { + Object o = new FromDemo().oneOfTwo(t1, t2); + if (o == null) { + System.out.println("1"); + } + } +} @NotNullByDefault public class JetBrainsNotNullByDefault { @@ -142,4 +183,4 @@ class InheritNotNullByDefault { interface NullableMember { String get(String s); } -} \ No newline at end of file +}