mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix some stub/AST inconsistencies in java PsiClass
* getContainingClass worked differently for local classes * supertype generic parameters could be resolved to null if AST loading occurred concurrently
This commit is contained in:
+2
-9
@@ -19,8 +19,6 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl;
|
||||
import com.intellij.psi.impl.java.stubs.JavaClassReferenceListElementType;
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassReferenceListStub;
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassStub;
|
||||
import com.intellij.psi.impl.source.PsiClassImpl;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl;
|
||||
import com.intellij.psi.stubs.StubBase;
|
||||
@@ -72,7 +70,7 @@ public class PsiClassReferenceListStubImpl extends StubBase<PsiReferenceList> im
|
||||
final boolean compiled = ((JavaClassReferenceListElementType)getStubType()).isCompiled(this);
|
||||
if (compiled) {
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
types[i] = new PsiClassReferenceType(new ClsJavaCodeReferenceElementImpl(getPsi(), StringRef.toString(myNames[i])), null);
|
||||
types[i] = new PsiClassReferenceType(new ClsJavaCodeReferenceElementImpl(getPsi(), myNames[i].toString()), null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -81,13 +79,8 @@ public class PsiClassReferenceListStubImpl extends StubBase<PsiReferenceList> im
|
||||
int nullCount = 0;
|
||||
final PsiReferenceList psi = getPsi();
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
PsiElement context = psi;
|
||||
if (getParentStub() instanceof PsiClassStub) {
|
||||
context = ((PsiClassImpl)getParentStub().getPsi()).calcBasesResolveContext(PsiNameHelper.getShortClassName(StringRef.toString(myNames[i])), psi);
|
||||
}
|
||||
|
||||
try {
|
||||
final PsiJavaCodeReferenceElement ref = factory.createReferenceFromText(StringRef.toString(myNames[i]), context);
|
||||
final PsiJavaCodeReferenceElement ref = factory.createReferenceFromText(myNames[i].toString(), psi);
|
||||
((PsiJavaCodeReferenceElementImpl)ref).setKindWhenDummy(PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND);
|
||||
types[i] = factory.createType(ref);
|
||||
}
|
||||
|
||||
@@ -28,10 +28,11 @@ import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.*;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassInitializerStub;
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassStub;
|
||||
import com.intellij.psi.impl.java.stubs.PsiMethodStub;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.psi.impl.source.tree.CompositeElement;
|
||||
import com.intellij.psi.impl.source.tree.SharedImplUtil;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
@@ -40,7 +41,6 @@ import com.intellij.psi.stubs.PsiFileStub;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -245,13 +245,7 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
|
||||
final PsiClassStub stub = getStub();
|
||||
if (stub != null) {
|
||||
StubElement parent = stub.getParentStub();
|
||||
while (parent != null && !(parent instanceof PsiClassStub)) {
|
||||
parent = parent.getParentStub();
|
||||
}
|
||||
|
||||
if (parent != null) {
|
||||
return ((PsiClassStub<? extends PsiClass>)parent).getPsi();
|
||||
}
|
||||
return parent instanceof PsiClassStub ? ((PsiClassStub<?>)parent).getPsi() : null;
|
||||
}
|
||||
|
||||
PsiElement parent = getParent();
|
||||
@@ -265,10 +259,29 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
|
||||
|
||||
@Override
|
||||
public PsiElement getContext() {
|
||||
final PsiClass cc = getContainingClass();
|
||||
return cc != null ? cc : super.getContext();
|
||||
StubElement contextStub = getContextStub();
|
||||
if (contextStub != null) {
|
||||
return contextStub.getPsi();
|
||||
}
|
||||
|
||||
return super.getContext();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private StubElement getContextStub() {
|
||||
PsiClassStub<?> stub = getStub();
|
||||
if (stub == null) return null;
|
||||
|
||||
// if AST is not loaded, then we only can need context to resolve supertype references
|
||||
// this can be done by stubs unless there are local/anonymous classes referencing other local classes
|
||||
StubElement parent = stub.getParentStub();
|
||||
if (parent instanceof PsiClassInitializerStub || parent instanceof PsiMethodStub) {
|
||||
if (parent.getChildrenByType(JavaStubElementTypes.CLASS, PsiElement.ARRAY_FACTORY).length <= 1) {
|
||||
parent = parent.getParentStub();
|
||||
}
|
||||
}
|
||||
return parent instanceof PsiClassStub ? parent : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
|
||||
@@ -16,12 +16,18 @@
|
||||
package com.intellij.psi
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.psi.impl.source.PsiClassImpl
|
||||
import com.intellij.psi.impl.source.PsiFileImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.searches.AnnotatedElementsSearch
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
class JavaStubsTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
void "test resolve from annotation method default"() {
|
||||
@@ -95,4 +101,32 @@ class JavaStubsTest extends LightCodeInsightFixtureTestCase {
|
||||
assert m1.getCanonicalText(true) == "@Foo.TA int"
|
||||
assert p1.getCanonicalText(true) == "@Foo.TA int"
|
||||
}
|
||||
|
||||
public void "test containing class of an local class is null"() {
|
||||
def foo = myFixture.addClass("class Foo {{ class Bar extends Foo {} }}")
|
||||
def bar = ClassInheritorsSearch.search(foo).findFirst()
|
||||
|
||||
def file = (PsiFileImpl)foo.containingFile
|
||||
assert !file.contentsLoaded
|
||||
|
||||
assert bar.containingClass == null
|
||||
assert !file.contentsLoaded
|
||||
|
||||
bar.node
|
||||
assert bar.containingClass == null
|
||||
assert file.contentsLoaded
|
||||
}
|
||||
|
||||
public void "test stub-based super class type parameter resolve"() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
def foo = myFixture.addClass("class Foo$i<T> {}")
|
||||
def bar = myFixture.addClass("class Bar$i<T> extends Foo$i<T> {}")
|
||||
|
||||
def app = ApplicationManager.application
|
||||
app.executeOnPooledThread({ ReadAction.compute { bar.node } })
|
||||
def superType = app.executeOnPooledThread({ ReadAction.compute { bar.superTypes[0] }} as Callable<PsiClassType>).get()
|
||||
assert foo == superType.resolve()
|
||||
assert bar.typeParameters[0] == PsiUtil.resolveClassInClassTypeOnly(superType.parameters[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user