diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/util/CompilerPathUtil.java b/compiler/cli/src/org/jetbrains/jet/cli/common/util/CompilerPathUtil.java index 872c644b132..1d2e60f0391 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/common/util/CompilerPathUtil.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/common/util/CompilerPathUtil.java @@ -16,8 +16,6 @@ package org.jetbrains.jet.cli.common.util; -import com.intellij.openapi.application.PathManager; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.utils.PathUtil; @@ -32,7 +30,7 @@ public class CompilerPathUtil { @Nullable public static File getSDKHome() { - final File compilerJar = new File(getJarPathForClass(CompilerPathUtil.class)); + final File compilerJar = new File(PathUtil.getJarPathForClass(CompilerPathUtil.class)); if (!compilerJar.exists()) return null; if (compilerJar.getName().equals(PathUtil.KOTLIN_COMPILER_JAR)) { @@ -61,10 +59,4 @@ public class CompilerPathUtil { public static File getJdkAnnotationsPath() { return PathUtil.getJdkAnnotationsPath(getSDKHome()); } - - @NotNull - public static String getJarPathForClass(@NotNull final Class aClass) { - final String resourceRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); - return new File(resourceRoot).getAbsoluteFile().getAbsolutePath(); - } } diff --git a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java index 66d610078ce..be6eadbb0c2 100644 --- a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java +++ b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java @@ -19,6 +19,7 @@ */ package org.jetbrains.jet.utils; +import com.intellij.openapi.application.PathManager; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; @@ -94,6 +95,12 @@ public class PathUtil { } } + @NotNull + public static String getJarPathForClass(@NotNull final Class aClass) { + final String resourceRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); + return new File(resourceRoot).getAbsoluteFile().getAbsolutePath(); + } + public static File findRtJar() { String javaHome = System.getProperty("java.home"); if ("jre".equals(new File(javaHome).getName())) { diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 850a7293a4a..0dffbb202bf 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -8,6 +8,12 @@ JUnit + + + org.jetbrains.jet.plugin.sdk.BundledKotlinSdkLibraryCreator + + + org.jetbrains.jet.plugin.JetStandardLibraryInitializer diff --git a/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java b/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java index dd7fae4c3f4..08d83d420ba 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java @@ -88,19 +88,6 @@ public class JetPluginUtil { public static Module getModuleForKotlinFile(@NotNull final VirtualFile file, @NotNull final Project project) { if (file.getFileType() != JetFileType.INSTANCE) return null; if (CompilerManager.getInstance(project).isExcludedFromCompilation(file)) return null; - - final Module module = ModuleUtil.findModuleForFile(file, project); - if (module == null || isMavenModule(module)) return null; - - return module; - } - - private static boolean isMavenModule(@NotNull final Module module) { - for (final VirtualFile root : ModuleRootManager.getInstance(module).getContentRoots()) { - if (root.findChild("pom.xml") != null) { - return true; - } - } - return false; + return ModuleUtil.findModuleForFile(file, project); } } diff --git a/idea/src/org/jetbrains/jet/plugin/OutdatedKotlinRuntimeNotification.java b/idea/src/org/jetbrains/jet/plugin/OutdatedKotlinRuntimeNotification.java index c65ba350dd1..a2606b733f5 100644 --- a/idea/src/org/jetbrains/jet/plugin/OutdatedKotlinRuntimeNotification.java +++ b/idea/src/org/jetbrains/jet/plugin/OutdatedKotlinRuntimeNotification.java @@ -151,7 +151,7 @@ public class OutdatedKotlinRuntimeNotification implements ModuleComponent { Library kotlinRuntime = table.getLibraryByName(ConfigureKotlinLibraryNotificationProvider.LIBRARY_NAME); if (kotlinRuntime != null) { for (VirtualFile root : kotlinRuntime.getFiles(OrderRootType.CLASSES)) { - if (root.getName().equals(ConfigureKotlinLibraryNotificationProvider.KOTLIN_RUNTIME_JAR)) { + if (root.getName().equals(PathUtil.KOTLIN_RUNTIME_JAR)) { return root; } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java index 71bb193f35a..42eddad4558 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ConfigureKotlinLibraryNotificationProvider.java @@ -56,6 +56,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.plugin.JetPluginUtil; import org.jetbrains.jet.plugin.sdk.KotlinSdkUtil; import org.jetbrains.jet.plugin.util.PluginPathUtil; +import org.jetbrains.jet.utils.PathUtil; import javax.swing.*; import java.io.File; @@ -66,7 +67,6 @@ import static org.jetbrains.jet.plugin.project.JsModuleDetector.isJsModule; public class ConfigureKotlinLibraryNotificationProvider implements EditorNotifications.Provider { private static final Key KEY = Key.create("configure.kotlin.library"); public static final String LIBRARY_NAME = "KotlinRuntime"; - public static final String KOTLIN_RUNTIME_JAR = "kotlin-runtime.jar"; private final Project myProject; @Override @@ -85,7 +85,7 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific final Module module = JetPluginUtil.getModuleForKotlinFile(file, myProject); if (module == null) return null; - if (isJsModule(module)) return null; + if (isMavenModule(module) || isJsModule(module)) return null; if (!KotlinSdkUtil.isSDKConfiguredFor(module)) return null; @@ -110,7 +110,7 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific Library kotlinRuntime = table.getLibraryByName(LIBRARY_NAME); if (kotlinRuntime != null) { for (VirtualFile root : kotlinRuntime.getFiles(OrderRootType.CLASSES)) { - if (root.getName().equals(KOTLIN_RUNTIME_JAR)) { + if (root.getName().equals(PathUtil.KOTLIN_RUNTIME_JAR)) { return kotlinRuntime; } } @@ -247,6 +247,15 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific }); } + private static boolean isMavenModule(@NotNull final Module module) { + for (final VirtualFile root : ModuleRootManager.getInstance(module).getContentRoots()) { + if (root.findChild("pom.xml") != null) { + return true; + } + } + return false; + } + private static class ChoosePathDialog extends DialogWrapper { private final Project myProject; private TextFieldWithBrowseButton myPathField; diff --git a/idea/src/org/jetbrains/jet/plugin/sdk/BundledKotlinSdkLibraryCreator.java b/idea/src/org/jetbrains/jet/plugin/sdk/BundledKotlinSdkLibraryCreator.java new file mode 100644 index 00000000000..2e9fa83bde7 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/sdk/BundledKotlinSdkLibraryCreator.java @@ -0,0 +1,83 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.sdk; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.util.PluginPathUtil; + +import java.io.File; +import java.util.Arrays; + +/** + * @author Maxim.Manuylov + * Date: 23.07.12 + */ +public class BundledKotlinSdkLibraryCreator implements ApplicationComponent { + @Override + public void initComponent() { + createBundledSdkLibraryIfNeeded(); + } + + private static void createBundledSdkLibraryIfNeeded() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + final LibrariesContainer librariesContainer = LibrariesContainerFactory.createContainer((Project) null); + if (!bundledSdkLibraryExists(librariesContainer)) { + final File bundledSDKHome = PluginPathUtil.getBundledSDKHome(); + if (bundledSDKHome != null) { + final String version = KotlinSdkUtil.getSDKVersion(bundledSDKHome); + if (version != null) { + final NewLibraryEditor editor = new NewLibraryEditor(); + editor.setName(KotlinSdkUtil.getSDKName(bundledSDKHome, version)); + KotlinSdkDescription.addSDKRoots(editor, bundledSDKHome); + librariesContainer.createLibrary(editor, LibrariesContainer.LibraryLevel.GLOBAL); + } + } + } + } + }); + } + + private static boolean bundledSdkLibraryExists(@NotNull final LibrariesContainer librariesContainer) { + final Library[] globalLibraries = librariesContainer.getLibraries(LibrariesContainer.LibraryLevel.GLOBAL); + for (final Library library : globalLibraries) { + final File sdkHome = KotlinSdkUtil.detectSDKHome(Arrays.asList(library.getFiles(OrderRootType.CLASSES))); + if (sdkHome != null && KotlinSdkUtil.isBundledSDK(sdkHome)) { + return true; + } + } + return false; + } + + @Override + public void disposeComponent() {} + + @NotNull + @Override + public String getComponentName() { + return getClass().getName(); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkDescription.java b/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkDescription.java index 9a675b349ae..c20591fc0bc 100644 --- a/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkDescription.java +++ b/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkDescription.java @@ -80,7 +80,7 @@ public class KotlinSdkDescription extends CustomLibraryDescription { return null; } - return new NewLibraryConfiguration(KotlinSdkUtil.getSDKName(sdkVersion)) { + return new NewLibraryConfiguration(KotlinSdkUtil.getSDKName(sdkHome, sdkVersion)) { @Override public void addRoots(@NotNull final LibraryEditor editor) { addSDKRoots(editor, sdkHome); diff --git a/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkPresentationProvider.java b/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkPresentationProvider.java index 603644fd4d1..435bb60623c 100644 --- a/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkPresentationProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkPresentationProvider.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.plugin.JetIcons; import javax.swing.*; +import java.io.File; import java.util.List; /** @@ -43,13 +44,15 @@ public class KotlinSdkPresentationProvider extends LibraryPresentationProvider classesRoots) { - final String sdkVersion = KotlinSdkUtil.detectSDKVersion(classesRoots); - return sdkVersion == null ? null : new KotlinSdkProperties(sdkVersion); + final File sdkHome = KotlinSdkUtil.detectSDKHome(classesRoots); + if (sdkHome == null) return null; + final String sdkVersion = KotlinSdkUtil.getSDKVersion(sdkHome); + return sdkVersion == null ? null : new KotlinSdkProperties(sdkHome, sdkVersion); } } diff --git a/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkProperties.java b/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkProperties.java index fcb3633904d..935260464ee 100644 --- a/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkProperties.java +++ b/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkProperties.java @@ -18,19 +18,27 @@ package org.jetbrains.jet.plugin.sdk; import com.intellij.openapi.roots.libraries.LibraryProperties; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; + +import java.io.File; /** * @author Maxim.Manuylov * Date: 19.05.12 */ public class KotlinSdkProperties extends LibraryProperties { + @NotNull private File mySdkHome; @NotNull private String myVersion; - public KotlinSdkProperties(@NotNull final String version) { + public KotlinSdkProperties(@NotNull final File sdkHome, @NotNull final String version) { + mySdkHome = sdkHome; myVersion = version; } + @NotNull + public File getSdkHome() { + return mySdkHome; + } + @NotNull public String getVersion() { return myVersion; @@ -43,16 +51,27 @@ public class KotlinSdkProperties extends LibraryProperties @Override public void loadState(@NotNull final KotlinSdkProperties state) { + mySdkHome = state.mySdkHome; myVersion = state.myVersion; } @Override - public boolean equals(@Nullable final Object that) { - return this == that || (that instanceof KotlinSdkProperties && myVersion.equals(((KotlinSdkProperties)that).myVersion)); + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof KotlinSdkProperties)) return false; + + KotlinSdkProperties that = (KotlinSdkProperties) o; + + if (!mySdkHome.equals(that.mySdkHome)) return false; + if (!myVersion.equals(that.myVersion)) return false; + + return true; } @Override public int hashCode() { - return myVersion.hashCode(); + int result = mySdkHome.hashCode(); + result = 31 * result + myVersion.hashCode(); + return result; } } diff --git a/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkUtil.java b/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkUtil.java index 06c45e1c807..5eba0b14344 100644 --- a/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/sdk/KotlinSdkUtil.java @@ -24,6 +24,7 @@ import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.plugin.util.PluginPathUtil; import org.jetbrains.jet.utils.PathUtil; import java.io.File; @@ -46,7 +47,7 @@ public class KotlinSdkUtil { @NotNull @Override public KotlinSdkProperties createDefaultProperties() { - return new KotlinSdkProperties(""); + return new KotlinSdkProperties(new File(""), ""); } }; @NotNull private static final String[] KOTLIN_COMPILER_JAR_ENTRY_NAMES = { @@ -101,13 +102,7 @@ public class KotlinSdkUtil { } @Nullable - public static String detectSDKVersion(@NotNull final List jars) { - final File sdkHome = detectSDKHome(jars); - return sdkHome == null ? null : getSDKVersion(sdkHome); - } - - @Nullable - private static File detectSDKHome(@NotNull final List jars) { + public static File detectSDKHome(@NotNull final List jars) { for (VirtualFile jar : jars) { jar = prepare(jar); if (jar == null) continue; @@ -194,9 +189,13 @@ public class KotlinSdkUtil { } } + public static boolean isBundledSDK(@NotNull final File sdkHome) { + return sdkHome.equals(PluginPathUtil.getBundledSDKHome()); + } + @NotNull - public static String getSDKName(@NotNull final String version) { - return "Kotlin " + version; + public static String getSDKName(@NotNull final File sdkHome, @NotNull final String version) { + return "Kotlin " + version + (isBundledSDK(sdkHome) ? " (bundled)" : ""); } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/util/PluginPathUtil.java b/idea/src/org/jetbrains/jet/plugin/util/PluginPathUtil.java index 55d8d02be4a..d51eff4c422 100644 --- a/idea/src/org/jetbrains/jet/plugin/util/PluginPathUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/util/PluginPathUtil.java @@ -31,6 +31,23 @@ import java.io.File; public class PluginPathUtil { private PluginPathUtil() {} + @Nullable + public static File getBundledSDKHome() { + final File plugin_jar_path = new File(PathUtil.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; + } + + return null; + } + @Nullable public static File getRuntimePath(@NotNull final Module module) { return PathUtil.getRuntimePath(KotlinSdkUtil.getSDKHomeFor(module));