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;