diff --git a/.idea/modules.xml b/.idea/modules.xml index c1f4844a4d1..78be03f7e92 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -16,6 +16,7 @@ + diff --git a/compiler/frontend.java/frontend.java.iml b/compiler/frontend.java/frontend.java.iml index 94b95ad5bde..2178d5b523e 100644 --- a/compiler/frontend.java/frontend.java.iml +++ b/compiler/frontend.java/frontend.java.iml @@ -10,6 +10,7 @@ + diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 76b3c548290..fa84832556a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -16,6 +16,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.java.alt.AltClassFinder; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.plugin.JetFileType; @@ -124,6 +125,7 @@ public class JavaDescriptorResolver { protected final JavaPsiFacade javaFacade; protected final GlobalSearchScope javaSearchScope; protected final JavaSemanticServices semanticServices; + private final AltClassFinder altClassFinder; public JavaDescriptorResolver(Project project, JavaSemanticServices semanticServices) { this.javaFacade = JavaPsiFacade.getInstance(project); @@ -141,6 +143,7 @@ public class JavaDescriptorResolver { } }; this.semanticServices = semanticServices; + altClassFinder = new AltClassFinder(project); } public static boolean isInJdkHeaders(VirtualFile file) { @@ -656,6 +659,8 @@ public class JavaDescriptorResolver { } private PsiClass findClass(String qualifiedName) { + PsiClass altClass = altClassFinder.findClass(qualifiedName); + if (altClass != null) return altClass; return javaFacade.findClass(qualifiedName, javaSearchScope); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/alt/AltClassFinder.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/alt/AltClassFinder.java new file mode 100644 index 00000000000..46ef8648e9f --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/alt/AltClassFinder.java @@ -0,0 +1,60 @@ +/* + * @author max + */ +package org.jetbrains.jet.lang.resolve.java.alt; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassOwner; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.compiler.PathUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class AltClassFinder { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.jet.lang.resolve.java.alt.AltClassFinder"); + + private final PsiManager psiManager; + private final List roots = new ArrayList(); + + public AltClassFinder(Project project) { + psiManager = PsiManager.getInstance(project); + + File alts = PathUtil.getAltHeadersPath(); + + if (alts != null) { + for (File root : alts.listFiles()) { + VirtualFile jarRoot = VirtualFileManager.getInstance().findFileByUrl("jar://" + root.getPath() + "!/"); + roots.add(jarRoot); + } + } + } + + public PsiClass findClass(@NotNull String qualifiedName) { + for (final VirtualFile classRoot : roots) { + final VirtualFile classFile = classRoot.findFileByRelativePath(qualifiedName.replace('.', '/') + ".class"); + if (classFile != null) { + if (!classFile.isValid()) { + LOG.error("Invalid child of valid parent: " + classFile.getPath() + "; " + classRoot.isValid() + " path=" + classRoot.getPath()); + return null; + } + final PsiFile file = psiManager.findFile(classFile); + if (file instanceof PsiClassOwner) { + final PsiClass[] classes = ((PsiClassOwner) file).getClasses(); + if (classes.length == 1) { + return classes[0]; + } + } + } + } + + return null; + } +} diff --git a/compiler/util/src/org/jetbrains/jet/plugin/compiler/PathUtil.java b/compiler/util/src/org/jetbrains/jet/plugin/compiler/PathUtil.java new file mode 100644 index 00000000000..b749aa871d3 --- /dev/null +++ b/compiler/util/src/org/jetbrains/jet/plugin/compiler/PathUtil.java @@ -0,0 +1,59 @@ +/* + * @author max + */ +package org.jetbrains.jet.plugin.compiler; + +import com.intellij.openapi.application.PathManager; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +public class PathUtil { + private PathUtil() {} + + public static File getDefaultCompilerPath() { + File plugin_jar_path = new File(getJarPathForClass(PathUtil.class)); + + if (!plugin_jar_path.exists()) return null; + + if (plugin_jar_path.getName().equals("kotlin-plugin.jar")) { + File lib = plugin_jar_path.getParentFile(); + File pluginHome = lib.getParentFile(); + + File answer = new File(pluginHome, "kotlinc"); + + return answer.exists() ? answer : null; + } + + if (plugin_jar_path.getName().equals("kotlin-compiler.jar")) { + File lib = plugin_jar_path.getParentFile(); + File answer = lib.getParentFile(); + return answer.exists() ? answer : null; + } + + return null; + } + + public static File getDefaultRuntimePath() { + File compilerPath = getDefaultCompilerPath(); + if (compilerPath == null) return null; + + File answer = new File(compilerPath, "lib/kotlin-runtime.jar"); + + return answer.exists() ? answer : null; + } + + public static File getAltHeadersPath() { + File compilerPath = getDefaultCompilerPath(); + if (compilerPath == null) return null; + + File answer = new File(compilerPath, "lib/alt"); + return answer.exists() ? answer : null; + } + + @NotNull + public static String getJarPathForClass(@NotNull Class aClass) { + String resourceRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); + return new File(resourceRoot).getAbsoluteFile().getAbsolutePath(); + } +} diff --git a/compiler/util/util.iml b/compiler/util/util.iml new file mode 100644 index 00000000000..c03fc491744 --- /dev/null +++ b/compiler/util/util.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 1ce3fcb7702..8dc6a3e3536 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -79,8 +79,6 @@ - - diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JdkHeadersFinder.java b/idea/src/org/jetbrains/jet/plugin/caches/JdkHeadersFinder.java deleted file mode 100644 index 507365e2c55..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/caches/JdkHeadersFinder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * @author max - */ -package org.jetbrains.jet.plugin.caches; - -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.NonClasspathClassFinder; -import org.jetbrains.jet.plugin.compiler.CompilerUtil; - -import java.io.File; -import java.util.Collections; -import java.util.List; - -public class JdkHeadersFinder extends NonClasspathClassFinder { - public JdkHeadersFinder(Project project) { - super(project); - } - - @Override - protected List calcClassRoots() { - File jdk_headers = CompilerUtil.getJdkHeadersPath(); - if (jdk_headers == null) return Collections.emptyList(); - - VirtualFile jarVfs = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(jdk_headers); - if (jarVfs == null) return Collections.emptyList(); - jarVfs.refresh(true, false); - - return Collections.singletonList(JarFileSystem.getInstance().getJarRootForLocalFile(jarVfs)); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/CompilerUtil.java b/idea/src/org/jetbrains/jet/plugin/compiler/CompilerUtil.java deleted file mode 100644 index ce05bf266f1..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/compiler/CompilerUtil.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * @author max - */ -package org.jetbrains.jet.plugin.compiler; - -import com.intellij.util.PathUtil; - -import java.io.File; - -public class CompilerUtil { - public static File getDefaultCompilerPath() { - File plugin_jar_path = new File(PathUtil.getJarPathForClass(CompilerUtil.class)); - - if (!plugin_jar_path.exists()) return null; - - File lib = plugin_jar_path.getParentFile(); - File pluginHome = lib.getParentFile(); - - File answer = new File(pluginHome, "kotlinc"); - - return answer.exists() ? answer : null; - } - - public static File getDefaultRuntimePath() { - File compilerPath = getDefaultCompilerPath(); - if (compilerPath == null) return null; - - File answer = new File(compilerPath, "lib/kotlin-runtime.jar"); - - return answer.exists() ? answer : null; - } - - public static File getJdkHeadersPath() { - File compilerPath = getDefaultCompilerPath(); - if (compilerPath == null) return null; - - File answer = new File(compilerPath, "lib/kotlin-jdk-headers.jar"); - - return answer.exists() ? answer : null; - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java index c54f3dd9fbd..b8dbc8b0d74 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java @@ -33,7 +33,7 @@ import com.intellij.ui.EditorNotificationPanel; import com.intellij.ui.EditorNotifications; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.plugin.JetFileType; -import org.jetbrains.jet.plugin.compiler.CompilerUtil; +import org.jetbrains.jet.plugin.compiler.PathUtil; import javax.swing.*; import java.io.File; @@ -95,7 +95,7 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific final Library kotlinRuntime = table.getLibraryByName("KotlinRuntime"); if (kotlinRuntime != null) return null; - File runtimePath = CompilerUtil.getDefaultRuntimePath(); + File runtimePath = PathUtil.getDefaultRuntimePath(); if (runtimePath == null) { Messages.showErrorDialog(myProject, "kotlin-runtime.jar is not found. Make sure plugin is properly installed.", "No Runtime Found"); return null;