[java-analysis] PsiSubstitutorImpl: better preserve context; more tests

GitOrigin-RevId: 4765f00cf6a5eafe902b9fae73c450f475e3d8c8
This commit is contained in:
Tagir Valeev
2024-10-08 17:46:27 +02:00
committed by intellij-monorepo-bot
parent f5463b7662
commit 8ea673ff41
4 changed files with 65 additions and 13 deletions

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -1,5 +1,46 @@
import org.jetbrains.annotations.*;
import java.util.List;
import java.util.Random;
@NotNullByDefault
class FromDemo {
native <T extends Number> T get();
public void test() {
Object o = new FromDemo().get();
if (<warning descr="Condition 'o == null' is always 'false'">o == null</warning>) {
System.out.println("1");
}
}
native <T extends Number> T get2();
public void test2() {
Object o = new FromDemo().get2();
if (<warning descr="Condition 'o == null' is always 'false'">o == null</warning>) {
System.out.println("1");
}
}
<T extends @Nullable Object> 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 (<warning descr="Condition 'o == null' is always 'false'">o == null</warning>) {
System.out.println("1");
}
}
public void test2(Object t1, Object t2) {
Object o = new FromDemo().oneOfTwo(t1, t2);
if (<warning descr="Condition 'o == null' is always 'false'">o == null</warning>) {
System.out.println("1");
}
}
}
@NotNullByDefault
public class JetBrainsNotNullByDefault {
@@ -142,4 +183,4 @@ class InheritNotNullByDefault {
interface NullableMember {
String get(String s);
}
}
}