Introduce VirtualFileFinder interface

Provide different implementations in Cli and Ide
This commit is contained in:
Pavel V. Talanov
2013-07-23 21:34:34 +04:00
parent b9f663a487
commit 52de4215b5
6 changed files with 167 additions and 2 deletions
@@ -51,7 +51,8 @@ import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lang.resolve.java.vfilefinder.CliVirtualFileFinder;
import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.utils.PathUtil;
@@ -67,6 +68,7 @@ public class JetCoreEnvironment {
private final JavaCoreApplicationEnvironment applicationEnvironment;
private final JavaCoreProjectEnvironment projectEnvironment;
private final List<JetFile> sourceFiles = new ArrayList<JetFile>();
private final ClassPath classPath = new ClassPath();
private final CoreExternalAnnotationsManager annotationsManager;
@@ -123,7 +125,10 @@ public class JetCoreEnvironment {
addSources(path);
}
JetScriptDefinitionProvider.getInstance(project).addScriptDefinitions(configuration.getList(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY));
JetScriptDefinitionProvider.getInstance(project).addScriptDefinitions(
configuration.getList(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY));
project.registerService(VirtualFileFinder.class, new CliVirtualFileFinder(classPath));
}
public CompilerConfiguration getConfiguration() {
@@ -194,6 +199,7 @@ public class JetCoreEnvironment {
return;
}
projectEnvironment.addJarToClassPath(path);
classPath.add(jarFile);
}
else {
VirtualFile root = applicationEnvironment.getLocalFileSystem().findFileByPath(path.getAbsolutePath());
@@ -202,6 +208,7 @@ public class JetCoreEnvironment {
return;
}
projectEnvironment.addSourcesToClasspath(root);
classPath.add(root);
}
}
@@ -0,0 +1,23 @@
package org.jetbrains.jet.cli.jvm.compiler;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public final class ClassPath implements Iterable<VirtualFile> {
@NotNull
private final List<VirtualFile> roots = new ArrayList<VirtualFile>();
@Override
public Iterator<VirtualFile> iterator() {
return roots.iterator();
}
public void add(@NotNull VirtualFile root) {
roots.add(root);
}
}
@@ -0,0 +1,72 @@
package org.jetbrains.jet.lang.resolve.java.vfilefinder;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.cli.jvm.compiler.ClassPath;
import org.jetbrains.jet.lang.resolve.java.resolver.KotlinClassFileHeader;
import org.jetbrains.jet.lang.resolve.name.FqName;
public class CliVirtualFileFinder implements VirtualFileFinder {
@NotNull
private final ClassPath classPath;
public CliVirtualFileFinder(@NotNull ClassPath path) {
classPath = path;
}
@Nullable
@Override
public VirtualFile find(@NotNull FqName className, @NotNull GlobalSearchScope scope) {
//TODO: use scope
return find(className);
}
@Nullable
@Override
public VirtualFile find(@NotNull FqName className) {
for (VirtualFile root : classPath) {
VirtualFile fileInRoot = findFileInRoot(className.asString(), root);
if (fileInRoot != null) {
return fileInRoot;
}
}
return null;
}
//NOTE: copied with some changes from CoreJavaFileManager
@Nullable
private static VirtualFile findFileInRoot(@NotNull String qName, @NotNull VirtualFile root) {
String pathRest = qName;
VirtualFile cur = root;
while (true) {
int dot = pathRest.indexOf('.');
if (dot < 0) break;
String pathComponent = pathRest.substring(0, dot);
VirtualFile child = cur.findChild(pathComponent);
if (child == null) break;
pathRest = pathRest.substring(dot + 1);
cur = child;
}
String className = pathRest.replace('.', '$');
VirtualFile vFile = cur.findChild(className + ".class");
if (vFile != null) {
if (!vFile.isValid()) {
//TODO: log
return null;
}
//NOTE: currently we use VirtualFileFinder to find Kotlin binaries only
if (KotlinClassFileHeader.readKotlinHeaderFromClassFile(vFile).getType() != KotlinClassFileHeader.HeaderType.NONE) {
return vFile;
}
}
return null;
}
}
@@ -0,0 +1,17 @@
package org.jetbrains.jet.lang.resolve.java.vfilefinder;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.name.FqName;
public interface VirtualFileFinder {
@Nullable
VirtualFile find(@NotNull FqName className, @NotNull GlobalSearchScope scope);
//NOTE: uses all scope by default
//TODO: should be removed, scope should always be passed
@Nullable
VirtualFile find(@NotNull FqName className);
}
+3
View File
@@ -88,6 +88,9 @@
<projectService serviceInterface="org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager"
serviceImplementation="org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager"/>
<projectService serviceInterface="org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder"
serviceImplementation="org.jetbrains.jet.plugin.vfilefinder.IDEVirtualFileFinder"/>
<projectService serviceInterface="org.jetbrains.jet.asJava.LightClassGenerationSupport"
serviceImplementation="org.jetbrains.jet.plugin.caches.resolve.IDELightClassGenerationSupport"/>
@@ -0,0 +1,43 @@
package org.jetbrains.jet.plugin.vfilefinder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.Collection;
public final class IDEVirtualFileFinder implements VirtualFileFinder {
private static final Logger LOG = Logger.getInstance(IDEVirtualFileFinder.class);
@NotNull private final Project project;
public IDEVirtualFileFinder(@NotNull Project project) {
this.project = project;
}
@Nullable
@Override
public VirtualFile find(@NotNull FqName className, @NotNull GlobalSearchScope scope) {
Collection<VirtualFile> files = FileBasedIndex.getInstance().getContainingFiles(KotlinClassFileIndex.KEY, className, scope);
if (files.isEmpty()) {
return null;
}
if (files.size() > 1) {
LOG.warn("There are " + files.size() + " classes with same fqName: " + className + " found.");
}
return files.iterator().next();
}
@Nullable
@Override
public VirtualFile find(@NotNull FqName className) {
return find(className, GlobalSearchScope.allScope(project));
}
}