Get containing with deferred stub evaluation

Tested in org.jetbrains.kotlin.idea.quickfix.QuickFixMultiFileTestGenerated.CreateFromUsage.CreateVariable.Parameter#testPlatformType
Resolve of Java element triggers resolve for all classes in package in IDE. One of them is Kotlin light class for package. In case when
some declarations in that packages has references to Java class from current package, compiler goes to recursion.
This commit is contained in:
Nikolay Krasko
2015-02-03 16:42:59 +03:00
parent c366da95ac
commit c9c3a1c924
2 changed files with 38 additions and 15 deletions
@@ -26,7 +26,6 @@ import com.intellij.psi.ClassFileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.compiled.ClsFileImpl;
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub;
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl;
@@ -359,20 +358,19 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
final PsiJavaFileStubImpl javaFileStub = new PsiJavaFileStubImpl(packageFqName.asString(), true);
javaFileStub.setPsiFactory(new ClsWrapperStubPsiFactory());
ClsFileImpl fakeFile =
new ClsFileImpl((PsiManagerImpl) manager, new ClassFileViewProvider(manager, virtualFile)) {
@NotNull
@Override
public PsiClassHolderFileStub getStub() {
return javaFileStub;
}
ClsFileImpl fakeFile = new ClsFileImpl(new ClassFileViewProvider(manager, virtualFile)) {
@NotNull
@Override
public PsiClassHolderFileStub getStub() {
return javaFileStub;
}
@NotNull
@Override
public String getPackageName() {
return packageFqName.asString();
}
};
@NotNull
@Override
public String getPackageName() {
return packageFqName.asString();
}
};
fakeFile.setPhysical(false);
javaFileStub.setPsi(fakeFile);
@@ -380,7 +378,7 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
}
@NotNull
private static VirtualFile getRepresentativeVirtualFile(@NotNull Collection<JetFile> files) {
public static VirtualFile getRepresentativeVirtualFile(@NotNull Collection<JetFile> files) {
JetFile firstFile = files.iterator().next();
VirtualFile virtualFile = files.size() == 1 ? firstFile.getVirtualFile() : new LightVirtualFile();
assert virtualFile != null : "No virtual file for " + firstFile;
@@ -20,11 +20,14 @@ import com.google.common.collect.Sets;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.compiled.ClsFileImpl;
import com.intellij.psi.impl.light.LightEmptyImplementsList;
import com.intellij.psi.impl.light.LightModifierList;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.PsiClassHolderFileStub;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
@@ -137,6 +140,7 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
private final CachedValue<KotlinPackageLightClassData> lightClassDataCache;
private final PsiModifierList modifierList;
private final LightEmptyImplementsList implementsList;
private final ClsFileImpl packageClsFile;
private KotlinLightClassForPackage(
@NotNull PsiManager manager,
@@ -154,6 +158,22 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
this.files = Sets.newHashSet(files); // needed for hashCode
this.hashCode = computeHashCode();
this.lightClassDataCache = FileStubCache.getInstance(getProject()).get(packageFqName, searchScope);
VirtualFile virtualFile = KotlinJavaFileStubProvider.getRepresentativeVirtualFile(files);
packageClsFile = new ClsFileImpl(new ClassFileViewProvider(PsiManager.getInstance(getProject()), virtualFile)) {
@NotNull
@Override
public PsiClassHolderFileStub getStub() {
return ((ClsFileImpl) getDelegate().getContainingFile()).getStub();
}
@NotNull
@Override
public String getPackageName() {
return KotlinLightClassForPackage.this.packageFqName.asString();
}
};
packageClsFile.setPhysical(false);
}
@Nullable
@@ -219,6 +239,11 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
return null;
}
@Override
public PsiFile getContainingFile() {
return packageClsFile;
}
@Override
public boolean hasTypeParameters() {
return false;