Fix resolve in sources files of libraries

This commit is contained in:
Natalia.Ukhorskaya
2013-03-27 17:36:14 +04:00
parent e1dece4345
commit f4a0808a28
2 changed files with 77 additions and 0 deletions
@@ -16,11 +16,15 @@
package org.jetbrains.jet.plugin.project;
import com.google.common.base.Predicates;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.LibraryUtil;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.PsiModificationTrackerImpl;
import com.intellij.psi.search.GlobalSearchScope;
@@ -33,11 +37,13 @@ import com.intellij.util.containers.SLRUCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.asJava.LightClassUtil;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.plugin.caches.resolve.KotlinDeclarationsCacheImpl;
@@ -119,6 +125,17 @@ public final class AnalyzerFacadeWithCache {
}
private static AnalyzeExhaust analyzeHeadersWithCacheOnFile(@NotNull JetFile fileToCache) {
VirtualFile virtualFile = fileToCache.getVirtualFile();
if (LightClassUtil.belongsToKotlinBuiltIns(fileToCache) ||
virtualFile != null && LibraryUtil.findLibraryEntry(virtualFile, fileToCache.getProject()) != null) {
/* For library sources we should resolve it, not only project files (as KotlinCacheManager do) */
return AnalyzerFacadeForJVM.INSTANCE.analyzeFiles(
fileToCache.getProject(),
Collections.singleton(fileToCache),
Collections.<AnalyzerScriptParameter>emptyList(),
Predicates.<PsiFile>alwaysFalse()
);
}
KotlinDeclarationsCache cache = KotlinCacheManager.getInstance(fileToCache.getProject()).getDeclarationsFromProject();
return ((KotlinDeclarationsCacheImpl) cache).getAnalyzeExhaust();
}
@@ -22,15 +22,24 @@ import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor;
import java.io.File;
import java.io.IOException;
public class NavigateToStdlibSourceRegressionTest extends NavigateToLibraryRegressionTest {
/**
@@ -41,6 +50,57 @@ public class NavigateToStdlibSourceRegressionTest extends NavigateToLibraryRegre
assertEquals("Test.kt", navigationElement.getContainingFile().getName());
}
public void testJavaClass() throws IOException {
doNavigationInSourcesTest("libraries/stdlib/src/kotlin/Iterators.kt", "Collections", "java.util.Collections");
}
public void testKotlinClass() throws IOException {
doNavigationInSourcesTest("libraries/stdlib/src/kotlin/Iterators.kt", "FunctionIterator", "kotlin.FunctionIterator");
}
public void testClassWithJavaAnalog() throws IOException {
doNavigationInSourcesTest("libraries/stdlib/src/kotlin/Iterators.kt", "Iterator", "jet.Iterator");
}
public void testNavigationInKotlinBuiltIns() throws IOException {
doNavigationInSourcesTest("libraries/stdlib/src/generated/_Arrays.kt", "Array", "jet.Array");
}
private void doNavigationInSourcesTest(@NotNull String path, @NotNull String element, @NotNull String expectedFqName) throws IOException {
File file = new File(path);
PsiFile psiFile = getPsiFileForFileFromSources(file);
String text = psiFile.getText();
int index = text.indexOf(element);
PsiReference ref = psiFile.findReferenceAt(index);
assertNotNull("Cannot find reference at " + index + ", " +
text.substring(index - 20, index) + "<caret>" + text.substring(index, index + 20), ref);
PsiElement resolvedElement = ref.resolve();
assertNotNull("Cannot resolve reference: " + ref.getElement().getText(), resolvedElement);
PsiElement navigationElement = resolvedElement.getNavigationElement();
checkNavigationElement(navigationElement, expectedFqName);
}
@NotNull
private PsiFile getPsiFileForFileFromSources(@NotNull File file) {
VirtualFile virtualFile = VfsUtil.findFileByIoFile(file, false);
assertNotNull("Cannot find virtual file for " + file.getAbsolutePath(), virtualFile);
PsiFile psiFile = getPsiManager().findFile(virtualFile);
assertNotNull("Cannot find psi file for " + virtualFile.getCanonicalPath(), psiFile);
return psiFile;
}
private void checkNavigationElement(@NotNull PsiElement element, @NotNull String expectedName) {
if (element instanceof PsiClass) {
assertEquals(expectedName, ((PsiClass) element).getQualifiedName());
}
else if (element instanceof JetClass) {
assertEquals(expectedName, JetPsiUtil.getFQName((JetClass) element).getFqName());
}
else {
fail("Navigation element should be JetClass or PsiClass: " + element.getClass() + ", " + element.getText());
}
}
@Override
protected void tearDown() throws Exception {
// Workaround for IDEA's bug during tests.