Reverted fix for KT-2042 Kotlin SDK must be explicitly specified for each module that uses Kotlin

#KT-2042 reopened
This commit is contained in:
Evgeny Gerashchenko
2012-07-31 18:19:40 +04:00
parent 1f3aa6699c
commit 942c1ee9d9
23 changed files with 140 additions and 1122 deletions
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.cli.common.CLIConfigurationKeys;
import org.jetbrains.jet.cli.common.CompilerPlugin;
import org.jetbrains.jet.cli.common.messages.MessageCollector;
import org.jetbrains.jet.cli.common.util.CompilerPathUtil;
import org.jetbrains.jet.cli.jvm.compiler.*;
import org.jetbrains.jet.config.CommonConfigurationKeys;
import org.jetbrains.jet.config.CompilerConfiguration;
@@ -69,7 +68,7 @@ public class BytecodeCompiler {
configuration.add(CLASSPATH_KEY, new File(stdlib));
}
else {
File path = CompilerPathUtil.getRuntimePath();
File path = PathUtil.getDefaultRuntimePath();
if (path != null) {
configuration.add(CLASSPATH_KEY, path);
}
@@ -79,7 +78,7 @@ public class BytecodeCompiler {
configuration.add(CLASSPATH_KEY, new File(path));
}
}
File jdkAnnotationsPath = CompilerPathUtil.getJdkAnnotationsPath();
File jdkAnnotationsPath = PathUtil.getJdkAnnotationsPath();
if (jdkAnnotationsPath != null) {
configuration.add(ANNOTATIONS_PATH_KEY, jdkAnnotationsPath);
}
@@ -1,62 +0,0 @@
/*
* 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.cli.common.util;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
/**
* @author Maxim.Manuylov
* Date: 20.05.12
*/
public class CompilerPathUtil {
private CompilerPathUtil() {}
@Nullable
public static File getSDKHome() {
File compilerJar = new File(PathUtil.getJarPathForClass(CompilerPathUtil.class));
if (!compilerJar.exists()) return null;
if (compilerJar.getName().equals(PathUtil.KOTLIN_COMPILER_JAR)) {
File lib = compilerJar.getParentFile();
File answer = lib.getParentFile();
return answer.exists() ? answer : null;
}
File current = new File("").getAbsoluteFile(); // CWD
do {
File atDevHome = new File(current, "dist/kotlinc");
if (atDevHome.exists()) return atDevHome;
current = current.getParentFile();
} while (current != null);
return null;
}
@Nullable
public static File getRuntimePath() {
return PathUtil.getRuntimePath(getSDKHome());
}
@Nullable
public static File getJdkAnnotationsPath() {
return PathUtil.getJdkAnnotationsPath(getSDKHome());
}
}
@@ -25,8 +25,10 @@ import org.jetbrains.jet.cli.common.CLICompiler;
import org.jetbrains.jet.cli.common.CLIConfigurationKeys;
import org.jetbrains.jet.cli.common.ExitCode;
import org.jetbrains.jet.cli.common.messages.*;
import org.jetbrains.jet.cli.common.util.CompilerPathUtil;
import org.jetbrains.jet.cli.jvm.compiler.*;
import org.jetbrains.jet.cli.jvm.compiler.CommandLineScriptUtils;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.cli.jvm.repl.ReplFromTerminal;
import org.jetbrains.jet.codegen.BuiltinToJavaTypesMapping;
import org.jetbrains.jet.codegen.CompilationException;
@@ -180,7 +182,7 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
classpath.add(PathUtil.findRtJar());
}
if (!arguments.noStdlib) {
classpath.add(CompilerPathUtil.getRuntimePath());
classpath.add(PathUtil.getDefaultRuntimePath());
}
if (arguments.classpath != null) {
for (String element : Splitter.on(File.pathSeparatorChar).split(arguments.classpath)) {
@@ -194,7 +196,7 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
private static List<File> getAnnotationsPath(@NotNull K2JVMCompilerArguments arguments) {
List<File> annotationsPath = Lists.newArrayList();
if (!arguments.noJdkAnnotations) {
annotationsPath.add(CompilerPathUtil.getJdkAnnotationsPath());
annotationsPath.add(PathUtil.getJdkAnnotationsPath());
}
if (arguments.annotations != null) {
for (String element : Splitter.on(File.pathSeparatorChar).split(arguments.annotations)) {
@@ -26,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.cli.common.CLIConfigurationKeys;
import org.jetbrains.jet.cli.common.messages.MessageCollector;
import org.jetbrains.jet.cli.common.util.CompilerPathUtil;
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GeneratedClassLoader;
@@ -89,12 +88,12 @@ public class CompileEnvironmentUtil {
}
};
CompilerConfiguration configuration = new CompilerConfiguration();
File defaultRuntimePath = CompilerPathUtil.getRuntimePath();
File defaultRuntimePath = PathUtil.getDefaultRuntimePath();
if (defaultRuntimePath != null) {
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, defaultRuntimePath);
}
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, PathUtil.findRtJar());
File jdkAnnotationsPath = CompilerPathUtil.getJdkAnnotationsPath();
File jdkAnnotationsPath = PathUtil.getJdkAnnotationsPath();
if (jdkAnnotationsPath != null) {
configuration.add(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, jdkAnnotationsPath);
}
@@ -123,7 +122,7 @@ public class CompileEnvironmentUtil {
}
private static List<Module> runDefineModules(String moduleFile, ClassFileFactory factory) {
File stdlibJar = CompilerPathUtil.getRuntimePath();
File stdlibJar = PathUtil.getDefaultRuntimePath();
GeneratedClassLoader loader;
if (stdlibJar != null) {
try {
@@ -32,7 +32,6 @@ import org.jetbrains.jet.cli.common.CLIConfigurationKeys;
import org.jetbrains.jet.cli.common.CompilerPlugin;
import org.jetbrains.jet.cli.common.CompilerPluginContext;
import org.jetbrains.jet.cli.common.messages.*;
import org.jetbrains.jet.cli.common.util.CompilerPathUtil;
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.config.CommonConfigurationKeys;
@@ -49,6 +48,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.plugin.JetMainDetector;
import org.jetbrains.jet.utils.ExceptionUtils;
import org.jetbrains.jet.utils.PathUtil;
import org.jetbrains.jet.utils.Progress;
import java.io.File;
@@ -250,7 +250,7 @@ public class KotlinToJVMBytecodeCompiler {
try {
GeneratedClassLoader classLoader = new GeneratedClassLoader(factory, new URLClassLoader(new URL[]{
// TODO: add all classpath
CompilerPathUtil.getRuntimePath().toURI().toURL()
PathUtil.getDefaultRuntimePath().toURI().toURL()
},
parentLoader == null ? AllModules.class.getClassLoader() : parentLoader));
JetFile scriptFile = environment.getSourceFiles().get(0);
@@ -364,7 +364,7 @@ public class KotlinToJVMBytecodeCompiler {
compilerConfiguration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector);
compilerConfiguration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, getClasspath(parentLoader));
compilerConfiguration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, Collections.singletonList(
CompilerPathUtil.getJdkAnnotationsPath()));
PathUtil.getJdkAnnotationsPath()));
compilerConfiguration.add(CommonConfigurationKeys.SOURCE_ROOTS_KEY, scriptPath);
compilerConfiguration.addAll(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY,
scriptDefinitions != null ? scriptDefinitions : Collections.<JetScriptDefinition>emptyList());
@@ -27,56 +27,82 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class PathUtil {
public static final String JS_LIB_JAR_NAME = "kotlin-jslib.jar";
public static final String JS_LIB_JS_NAME = "kotlinLib.js";
public static final String JDK_ANNOTATIONS_JAR = "kotlin-jdk-annotations.jar";
public static final String KOTLIN_COMPILER_JAR = "kotlin-compiler.jar";
public static final String KOTLIN_RUNTIME_JAR = "kotlin-runtime.jar";
private PathUtil() {}
@Nullable
public static File getRuntimePath(@Nullable File sdkHome) {
return getFilePackedIntoLib(sdkHome, KOTLIN_RUNTIME_JAR);
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;
}
File current = new File("").getAbsoluteFile(); // CWD
do {
File atDevHome = new File(current, "dist/kotlinc");
if (atDevHome.exists()) return atDevHome;
current = current.getParentFile();
} while (current != null);
return null;
}
@Nullable
public static File getCompilerPath(@Nullable File sdkHome) {
return getFilePackedIntoLib(sdkHome, KOTLIN_COMPILER_JAR);
public static File getDefaultRuntimePath() {
return getFilePackedIntoLib("kotlin-runtime.jar");
}
@Nullable
public static File getJsLibJsPath(@Nullable File sdkHome) {
return getFilePackedIntoLib(sdkHome, JS_LIB_JS_NAME);
public static File getDefaultJsLibJsPath() {
return getFilePackedIntoLib(JS_LIB_JS_NAME);
}
@Nullable
public static File getJsLibJarPath(@Nullable File sdkHome) {
return getFilePackedIntoLib(sdkHome, JS_LIB_JAR_NAME);
public static File getDefaultJsLibJarPath() {
return getFilePackedIntoLib(JS_LIB_JAR_NAME);
}
@Nullable
public static File getJdkAnnotationsPath(@Nullable File sdkHome) {
return getFilePackedIntoLib(sdkHome, JDK_ANNOTATIONS_JAR);
}
private static File getFilePackedIntoLib(@NotNull String filePathFromLib) {
File compilerPath = getDefaultCompilerPath();
if (compilerPath == null) return null;
File answer = new File(compilerPath, "lib/" + filePathFromLib);
@Nullable
private static File getFilePackedIntoLib(@Nullable File sdkHome, @NotNull String filePathFromLib) {
if (sdkHome == null) return null;
File answer = new File(sdkHome, "lib/" + filePathFromLib);
return answer.exists() ? answer : null;
}
@Nullable
public static File getSDKHomeByCompilerPath(@Nullable File compilerPath) {
if (compilerPath == null) return null;
File libDir = compilerPath.getParentFile();
if (libDir == null) return null;
File sdkHome = libDir.getParentFile();
return sdkHome != null && sdkHome.exists() ? sdkHome : null;
public static File getJdkAnnotationsPath() {
return getFilePackedIntoLib(JDK_ANNOTATIONS_JAR);
}
@NotNull
public static String getJarPathForClass(@NotNull Class aClass) {
String resourceRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class");
return new File(resourceRoot).getAbsoluteFile().getAbsolutePath();
}
@NotNull
@@ -95,12 +121,6 @@ public class PathUtil {
}
}
@NotNull
public static String getJarPathForClass(@NotNull Class aClass) {
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())) {
+3 -13
View File
@@ -8,12 +8,6 @@
<depends optional="true">JUnit</depends>
<application-components>
<component>
<implementation-class>org.jetbrains.jet.plugin.sdk.BundledKotlinSdkLibraryCreator</implementation-class>
</component>
</application-components>
<project-components>
<component>
<implementation-class>org.jetbrains.jet.plugin.JetStandardLibraryInitializer</implementation-class>
@@ -30,15 +24,15 @@
<component>
<implementation-class>org.jetbrains.jet.plugin.highlighter.DeclarationHintSupport</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.jet.plugin.OutdatedKotlinRuntimeNotification</implementation-class>
</component>
</project-components>
<module-components>
<component>
<implementation-class>org.jetbrains.jet.plugin.project.K2JSModuleComponent</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.jet.plugin.OutdatedKotlinRuntimeNotification</implementation-class>
</component>
</module-components>
<actions>
@@ -85,10 +79,6 @@
<errorHandler implementation="org.jetbrains.jet.plugin.reporter.KotlinReportSubmitter"/>
<framework.type implementation="org.jetbrains.jet.plugin.sdk.KotlinFrameworkType"/>
<library.presentationProvider implementation="org.jetbrains.jet.plugin.sdk.KotlinSdkPresentationProvider"/>
<editorNotificationProvider implementation="org.jetbrains.jet.plugin.sdk.KotlinSdkNotConfiguredNotificationProvider"/>
<internalFileTemplate name="Kotlin File"/>
<internalFileTemplate name="Kotlin Class"/>
<internalFileTemplate name="Kotlin Enum"/>
@@ -17,14 +17,8 @@
package org.jetbrains.jet.plugin;
import com.google.common.collect.Lists;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
@@ -83,11 +77,4 @@ public class JetPluginUtil {
}
return libraryScope == ((NamespaceDescriptor) declaration).getMemberScope();
}
@Nullable
public static Module getModuleForKotlinFile(@NotNull VirtualFile file, @NotNull Project project) {
if (file.getFileType() != JetFileType.INSTANCE) return null;
if (CompilerManager.getInstance(project).isExcludedFromCompilation(file)) return null;
return ModuleUtil.findModuleForFile(file, project);
}
}
@@ -14,16 +14,19 @@ package org.jetbrains.jet.plugin;/*
* limitations under the License.
*/
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleComponent;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.ui.Messages;
@@ -35,7 +38,6 @@ import com.intellij.util.text.VersionComparatorUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.quickfix.ConfigureKotlinLibraryNotificationProvider;
import org.jetbrains.jet.plugin.util.PluginPathUtil;
import org.jetbrains.jet.utils.PathUtil;
import javax.swing.event.HyperlinkEvent;
@@ -48,40 +50,36 @@ import java.util.jar.JarFile;
* @author Evgeny Gerashchenko
* @since 5/22/12
*/
public class OutdatedKotlinRuntimeNotification implements ModuleComponent {
public class OutdatedKotlinRuntimeNotification extends AbstractProjectComponent {
private static final String UNKNOWN_VERSION = "UNKNOWN";
private static final String SUPPRESSED_PROPERTY_NAME_PATTERN = "oudtdated.runtime.suppressed.plugin.version[%s]";
private static final String SUPPRESSED_PROPERTY_NAME = "oudtdated.runtime.suppressed.plugin.version";
private final Module myModule;
private final String mySuppressedPropertyName;
public OutdatedKotlinRuntimeNotification(Module module) {
myModule = module;
mySuppressedPropertyName = String.format(SUPPRESSED_PROPERTY_NAME_PATTERN, module.getName());
public OutdatedKotlinRuntimeNotification(final Project project) {
super(project);
}
@Override
public void projectOpened() {
if (ApplicationManager.getApplication().isInternal()) return;
String runtimeVersion = getRuntimeVersion(getKotlinRuntimeJar());
String runtimeVersion = getRuntimeVersion();
final String pluginVersion = getPluginVersion();
if (runtimeVersion == null) return; // runtime is not present in project
final String sdkVersion = getRuntimeVersion(getRuntimeFromSdk());
if (sdkVersion == null || "snapshot".equals(sdkVersion)) return; // plugin is run from sources or SDK is not configured for the module, can't compare versions
if ("@snapshot@".equals(pluginVersion)) return; // plugin is run from sources, can't compare versions
// user already clicked suppress
if (sdkVersion.equals(PropertiesComponent.getInstance(myModule.getProject()).getValue(mySuppressedPropertyName))) return;
if (pluginVersion.equals(PropertiesComponent.getInstance(myProject).getValue(SUPPRESSED_PROPERTY_NAME))) return;
boolean isRuntimeOutdated = "snapshot".equals(runtimeVersion)
|| UNKNOWN_VERSION.equals(runtimeVersion)
|| runtimeVersion.startsWith("internal-") != sdkVersion.startsWith("internal-")
|| VersionComparatorUtil.compare(sdkVersion, runtimeVersion) > 0;
|| runtimeVersion.startsWith("internal-") != pluginVersion.startsWith("internal-")
|| VersionComparatorUtil.compare(pluginVersion, runtimeVersion) > 0;
if (!isRuntimeOutdated) return;
String message = String.format("<p>Your version of Kotlin runtime library in module \"%s\" is %s, while Kotlin SDK version in this module is %s." +
String message = String.format("<p>Your version of Kotlin runtime library is %s, while plugin version is %s." +
" Runtime library should be updated to avoid compatibility problems.</p>" +
"<p><a href=\"update\">Update Runtime</a> <a href=\"ignore\">Ignore</a></p>",
myModule.getName(), UNKNOWN_VERSION.equals(runtimeVersion) ? "older than 0.1.2296" : runtimeVersion, sdkVersion);
UNKNOWN_VERSION.equals(runtimeVersion) ? "older than 0.1.2296" : runtimeVersion, pluginVersion);
Notifications.Bus.notify(new Notification("Outdated Kotlin Runtime", "Outdated Kotlin Runtime",
message,
NotificationType.WARNING, new NotificationListener() {
@@ -92,7 +90,7 @@ public class OutdatedKotlinRuntimeNotification implements ModuleComponent {
updateRuntime();
}
else if ("ignore".equals(event.getDescription())) {
PropertiesComponent.getInstance(myModule.getProject()).setValue(mySuppressedPropertyName, sdkVersion);
PropertiesComponent.getInstance(myProject).setValue(SUPPRESSED_PROPERTY_NAME, pluginVersion);
}
else {
throw new AssertionError();
@@ -100,17 +98,16 @@ public class OutdatedKotlinRuntimeNotification implements ModuleComponent {
notification.expire();
}
}
}), myModule.getProject());
}
}), myProject);
}
private void updateRuntime() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
File runtimePath = PluginPathUtil.getRuntimePath(myModule);
File runtimePath = PathUtil.getDefaultRuntimePath();
if (runtimePath == null) {
Messages.showErrorDialog(myModule.getProject(),
"\"kotlin-runtime.jar\" is not found. Make sure Kotlin SDK is configured for module \"" + myModule.getName() + "\".",
Messages.showErrorDialog(myProject, "kotlin-runtime.jar is not found. Make sure plugin is properly installed.",
"No Runtime Found");
return;
}
@@ -133,7 +130,8 @@ public class OutdatedKotlinRuntimeNotification implements ModuleComponent {
}
@Nullable
private static String getRuntimeVersion(@Nullable VirtualFile kotlinRuntimeJar) {
private String getRuntimeVersion() {
VirtualFile kotlinRuntimeJar = getKotlinRuntimeJar();
if (kotlinRuntimeJar == null) return null;
VirtualFile manifestFile = kotlinRuntimeJar.findFileByRelativePath(JarFile.MANIFEST_NAME);
if (manifestFile != null) {
@@ -147,11 +145,11 @@ public class OutdatedKotlinRuntimeNotification implements ModuleComponent {
@Nullable
private VirtualFile getKotlinRuntimeJar() {
LibraryTable table = ModuleRootManager.getInstance(myModule).getModifiableModel().getModuleLibraryTable();
LibraryTable table = ProjectLibraryTable.getInstance(myProject);
Library kotlinRuntime = table.getLibraryByName(ConfigureKotlinLibraryNotificationProvider.LIBRARY_NAME);
if (kotlinRuntime != null) {
for (VirtualFile root : kotlinRuntime.getFiles(OrderRootType.CLASSES)) {
if (root.getName().equals(PathUtil.KOTLIN_RUNTIME_JAR)) {
if (root.getName().equals(ConfigureKotlinLibraryNotificationProvider.KOTLIN_RUNTIME_JAR)) {
return root;
}
}
@@ -159,27 +157,10 @@ public class OutdatedKotlinRuntimeNotification implements ModuleComponent {
return null;
}
@Nullable
private VirtualFile getRuntimeFromSdk() {
File runtimePath = PluginPathUtil.getRuntimePath(myModule);
return runtimePath == null ? null : PathUtil.jarFileOrDirectoryToVirtualFile(runtimePath);
}
@Override
public void moduleAdded() {}
@Override
public void projectClosed() {}
@Override
public void initComponent() {}
@Override
public void disposeComponent() {}
@NotNull
@Override
public String getComponentName() {
return getClass().getName();
private static String getPluginVersion() {
IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId("org.jetbrains.kotlin"));
assert plugin != null : "How can it be? Kotlin plugin is available, but its component is running. Complete nonsense.";
return plugin.getVersion();
}
}
@@ -19,11 +19,12 @@ package org.jetbrains.jet.plugin.compiler;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import jet.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.sdk.KotlinSdkUtil;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
import java.io.*;
import static com.intellij.openapi.compiler.CompilerMessageCategory.ERROR;
@@ -36,16 +37,16 @@ public final class CompilerEnvironment {
public static CompilerEnvironment getEnvironmentFor(@NotNull CompileContext compileContext, @NotNull Module module, boolean tests) {
VirtualFile mainOutput = compileContext.getModuleOutputDirectory(module);
final VirtualFile outputDir = tests ? compileContext.getModuleOutputDirectoryForTests(module) : mainOutput;
File kotlinHome = KotlinSdkUtil.getSDKHomeFor(module);
return new CompilerEnvironment(module.getName(), kotlinHome, outputDir);
File kotlinHome = PathUtil.getDefaultCompilerPath();
return new CompilerEnvironment(kotlinHome, outputDir);
}
@NotNull private final String moduleName;
@Nullable private final File kotlinHome;
@Nullable private final VirtualFile output;
@Nullable
private final File kotlinHome;
@Nullable
private final VirtualFile output;
public CompilerEnvironment(@NotNull String moduleName, @Nullable File home, @Nullable VirtualFile output) {
this.moduleName = moduleName;
public CompilerEnvironment(@Nullable File home, @Nullable VirtualFile output) {
this.kotlinHome = home;
this.output = output;
}
@@ -71,7 +72,8 @@ public final class CompilerEnvironment {
compileContext.addMessage(ERROR, "[Internal Error] No output directory", "", -1, -1);
}
if (kotlinHome == null) {
compileContext.addMessage(ERROR, "Cannot find Kotlin SDK home. Make sure Kotlin SDK is configured for module \"" + moduleName + "\".", "", -1, -1);
compileContext.addMessage(ERROR, "Cannot find kotlinc home. Make sure plugin is properly installed", "", -1, -1);
}
}
}
@@ -20,11 +20,13 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.fileChooser.FileTextField;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
@@ -53,9 +55,7 @@ import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
import com.intellij.util.containers.ContainerUtil;
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.plugin.JetFileType;
import org.jetbrains.jet.utils.PathUtil;
import javax.swing.*;
@@ -65,9 +65,10 @@ import java.io.IOException;
import static org.jetbrains.jet.plugin.project.JsModuleDetector.isJsModule;
public class ConfigureKotlinLibraryNotificationProvider implements EditorNotifications.Provider<EditorNotificationPanel> {
private static Key<EditorNotificationPanel> KEY = Key.create("configure.kotlin.library");
public static String LIBRARY_NAME = "KotlinRuntime";
private Project myProject;
private static final Key<EditorNotificationPanel> 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
public Key<EditorNotificationPanel> getKey() {
@@ -82,12 +83,16 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
@Override
public EditorNotificationPanel createNotificationPanel(VirtualFile file) {
try {
Module module = JetPluginUtil.getModuleForKotlinFile(file, myProject);
if (file.getFileType() != JetFileType.INSTANCE) return null;
if (CompilerManager.getInstance(myProject).isExcludedFromCompilation(file)) return null;
final Module module = ModuleUtil.findModuleForFile(file, myProject);
if (module == null) return null;
if (isMavenModule(module) || isJsModule(module)) return null;
if (isMavenModule(module)) return null;
if (!KotlinSdkUtil.isSDKConfiguredFor(module)) return null;
if (isJsModule(module)) return null;
GlobalSearchScope scope = module.getModuleWithDependenciesAndLibrariesScope(false);
if (JavaPsiFacade.getInstance(myProject).findClass("jet.JetObject", scope) == null) {
@@ -105,20 +110,20 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
return null;
}
private Library findOrCreateRuntimeLibrary(@NotNull Module module) {
private Library findOrCreateRuntimeLibrary() {
LibraryTable table = ProjectLibraryTable.getInstance(myProject);
Library kotlinRuntime = table.getLibraryByName(LIBRARY_NAME);
if (kotlinRuntime != null) {
for (VirtualFile root : kotlinRuntime.getFiles(OrderRootType.CLASSES)) {
if (root.getName().equals(PathUtil.KOTLIN_RUNTIME_JAR)) {
if (root.getName().equals(KOTLIN_RUNTIME_JAR)) {
return kotlinRuntime;
}
}
}
File runtimePath = PluginPathUtil.getRuntimePath(module);
File runtimePath = PathUtil.getDefaultRuntimePath();
if (runtimePath == null) {
Messages.showErrorDialog(myProject, "\"kotlin-runtime.jar\" is not found. Make sure Kotlin SDK is configured for module \"" + module.getName() + "\".",
Messages.showErrorDialog(myProject, "kotlin-runtime.jar is not found. Make sure plugin is properly installed.",
"No Runtime Found");
return null;
}
@@ -146,7 +151,6 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
final Library finalKotlinRuntime = kotlinRuntime;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
Library.ModifiableModel model = finalKotlinRuntime.getModifiableModel();
model.addRoot(VfsUtil.getUrlForLibraryRoot(targetJar), OrderRootType.CLASSES);
@@ -159,7 +163,7 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
}
private EditorNotificationPanel createNotificationPanel(final Module module) {
EditorNotificationPanel answer = new EditorNotificationPanel();
final EditorNotificationPanel answer = new EditorNotificationPanel();
answer.setText("Kotlin is not configured for module '" + module.getName() + "'");
answer.createActionLabel("Set up module '" + module.getName() + "' as JVM Kotlin module", new Runnable() {
@@ -192,7 +196,7 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
Library library = findOrCreateRuntimeLibrary(module);
Library library = findOrCreateRuntimeLibrary();
if (library != null) {
ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
if (model.findLibraryOrderEntry(library) == null) {
@@ -214,7 +218,7 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
/* package */ static void addJdkAnnotations(Module module) {
Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
assert sdk != null;
File annotationsIoFile = PluginPathUtil.getJdkAnnotationsPath(module);
File annotationsIoFile = PathUtil.getJdkAnnotationsPath();
if (annotationsIoFile != null) {
VirtualFile jdkAnnotationsJar = LocalFileSystem.getInstance().findFileByIoFile(annotationsIoFile);
if (jdkAnnotationsJar != null) {
@@ -249,10 +253,9 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
private static boolean isMavenModule(@NotNull Module module) {
for (VirtualFile root : ModuleRootManager.getInstance(module).getContentRoots()) {
if (root.findChild("pom.xml") != null) {
return true;
}
if (root.findChild("pom.xml") != null) return true;
}
return false;
}
@@ -36,7 +36,6 @@ import com.intellij.psi.impl.PsiModificationTrackerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.project.K2JSModuleComponent;
import org.jetbrains.jet.plugin.util.PluginPathUtil;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
@@ -66,7 +65,7 @@ public final class JsModuleSetUp {
return;
}
if (!copyJsLibFiles(module, rootDir)) return;
if (!copyJsLibFiles(rootDir)) return;
setUpK2JSModuleComponent(module);
setUpLibraryAsSourceLibrary(module, rootDir);
@@ -109,11 +108,11 @@ public final class JsModuleSetUp {
DaemonCodeAnalyzer.getInstance(module.getProject()).restart();
}
private static boolean copyJsLibFiles(@NotNull Module module, @NotNull File rootDir) {
File jsLibJarPath = PluginPathUtil.getJsLibJarPath(module);
File jsLibJsPath = PluginPathUtil.getJsLibJsPath(module);
private static boolean copyJsLibFiles(@NotNull File rootDir) {
File jsLibJarPath = PathUtil.getDefaultJsLibJarPath();
File jsLibJsPath = PathUtil.getDefaultJsLibJsPath();
if ((jsLibJarPath == null) || (jsLibJsPath == null)) {
notifyFailure("JavaScript library not found. Make sure Kotlin SDK is configured for module \"" + module.getName() + "\".");
notifyFailure("JavaScript library not found. Make sure plugin is installed properly.");
return false;
}
@@ -1,83 +0,0 @@
/*
* 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() {
LibrariesContainer librariesContainer = LibrariesContainerFactory.createContainer((Project) null);
if (!bundledSdkLibraryExists(librariesContainer)) {
File bundledSDKHome = PluginPathUtil.getBundledSDKHome();
if (bundledSDKHome != null) {
String version = KotlinSdkUtil.getSDKVersion(bundledSDKHome);
if (version != null) {
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 LibrariesContainer librariesContainer) {
Library[] globalLibraries = librariesContainer.getLibraries(LibrariesContainer.LibraryLevel.GLOBAL);
for (Library library : globalLibraries) {
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();
}
}
@@ -1,56 +0,0 @@
/*
* 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.framework.addSupport.FrameworkSupportInModuleConfigurable;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModifiableModelsProvider;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinFrameworkSupportConfigurable extends FrameworkSupportInModuleConfigurable {
@Nullable
@Override
public JComponent createComponent() {
return null;
}
@NotNull
@Override
public CustomLibraryDescription createLibraryDescription() {
return new KotlinSdkDescription();
}
@Override
public boolean isOnlyLibraryAdded() {
return true;
}
@Override
public void addSupport(@NotNull Module module,
@NotNull ModifiableRootModel rootModel,
@NotNull ModifiableModelsProvider modifiableModelsProvider) {
}
}
@@ -1,51 +0,0 @@
/*
* 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.framework.FrameworkTypeEx;
import com.intellij.framework.addSupport.FrameworkSupportInModuleConfigurable;
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.ModuleType;
import org.jetbrains.annotations.NotNull;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinFrameworkSupportProvider extends FrameworkSupportInModuleProvider {
@NotNull private static final String PLUGIN_MODULE_ID = "PLUGIN_MODULE";
@NotNull private static final String ANDROID_MODULE_ID = "ANDROID_MODULE";
@NotNull
@Override
public FrameworkTypeEx getFrameworkType() {
return FrameworkTypeEx.EP_NAME.findExtension(KotlinFrameworkType.class);
}
@NotNull
@Override
public FrameworkSupportInModuleConfigurable createConfigurable(@NotNull FrameworkSupportModel model) {
return new KotlinFrameworkSupportConfigurable();
}
@Override
public boolean isEnabledForModuleType(@NotNull ModuleType type) {
return type instanceof JavaModuleType || PLUGIN_MODULE_ID.equals(type.getId()) || ANDROID_MODULE_ID.equals(type.getId());
}
}
@@ -1,52 +0,0 @@
/*
* 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.framework.FrameworkTypeEx;
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.plugin.JetIcons;
import javax.swing.*;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinFrameworkType extends FrameworkTypeEx {
public KotlinFrameworkType() {
super("Kotlin");
}
@NotNull
@Override
public FrameworkSupportInModuleProvider createProvider() {
return new KotlinFrameworkSupportProvider();
}
@NotNull
@Override
public String getPresentableName() {
return "Kotlin";
}
@NotNull
@Override
public Icon getIcon() {
return JetIcons.SMALL_LOGO;
}
}
@@ -1,129 +0,0 @@
/*
* 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.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.LibraryKind;
import com.intellij.openapi.roots.libraries.NewLibraryConfiguration;
import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinSdkDescription extends CustomLibraryDescription {
@NotNull
@Override
public Set<? extends LibraryKind> getSuitableLibraryKinds() {
return Collections.singleton(KotlinSdkUtil.getKotlinSdkLibraryKind());
}
@Nullable
@Override
public NewLibraryConfiguration createNewLibrary(@NotNull JComponent parentComponent, @Nullable VirtualFile contextDirectory) {
VirtualFile initial = findFile(System.getenv("KOTLIN_HOME"));
if (initial == null) {
initial = findFile(System.getProperty("kotlinHome"));
}
FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false) {
@Override
public boolean isFileSelectable(@Nullable VirtualFile file) {
return super.isFileSelectable(file) && KotlinSdkUtil.isSDKHome(file);
}
};
descriptor.setTitle("Kotlin SDK");
descriptor.setDescription("Choose a directory containing Kotlin distribution");
VirtualFile sdkHomeVFile = FileChooser.chooseFile(parentComponent, descriptor, initial);
if (sdkHomeVFile == null) return null;
final File sdkHome = new File(sdkHomeVFile.getPath());
String sdkVersion = KotlinSdkUtil.getSDKVersion(sdkHome);
if (sdkVersion == null) {
Messages.showErrorDialog(parentComponent,
"Failed to find Kotlin SDK in the specified path: cannot determine Kotlin version.",
"Failed to Find Kotlin SDK");
return null;
}
return new NewLibraryConfiguration(KotlinSdkUtil.getSDKName(sdkHome, sdkVersion)) {
@Override
public void addRoots(@NotNull LibraryEditor editor) {
addSDKRoots(editor, sdkHome);
}
};
}
@Nullable
private static VirtualFile findFile(@Nullable String path) {
if (StringUtil.isEmptyOrSpaces(path)) return null;
//noinspection ConstantConditions
return LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(path));
}
public static void addSDKRoots(@NotNull LibraryEditor editor, @NotNull File sdkHome) {
File libDir = new File(sdkHome, "lib");
if (!libDir.isDirectory()) return;
List<File> jars = new ArrayList<File>();
collectJars(libDir, jars);
for (File jar : jars) {
editor.addRoot(VfsUtil.getUrlForLibraryRoot(jar), OrderRootType.CLASSES);
}
}
private static void collectJars(@NotNull File dir, @NotNull List<File> jars) {
File[] children = dir.listFiles();
if (children == null) return;
for (File child : children) {
if (child.isDirectory()) {
collectJars(child, jars);
}
else if (child.isFile() && child.getName().endsWith(".jar")) {
jars.add(child);
}
}
}
@NotNull
@Override
public LibrariesContainer.LibraryLevel getDefaultLevel() {
return LibrariesContainer.LibraryLevel.GLOBAL;
}
}
@@ -1,95 +0,0 @@
/*
* 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.ProjectTopics;
import com.intellij.ide.util.frameworkSupport.AddFrameworkSupportDialog;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.JetPluginUtil;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinSdkNotConfiguredNotificationProvider implements EditorNotifications.Provider<EditorNotificationPanel> {
@NotNull private static final Key<EditorNotificationPanel> KEY = Key.create("configure.kotlin.sdk");
@NotNull private final Project myProject;
public KotlinSdkNotConfiguredNotificationProvider(@NotNull Project project, @NotNull final EditorNotifications notifications) {
myProject = project;
project.getMessageBus().connect(project).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
@Override
public void beforeRootsChange(ModuleRootEvent event) {}
@Override
public void rootsChanged(ModuleRootEvent event) {
notifications.updateAllNotifications();
}
});
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Nullable
@Override
public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file) {
try {
Module module = JetPluginUtil.getModuleForKotlinFile(file, myProject);
if (module == null) return null;
if (!KotlinSdkUtil.isSDKConfiguredFor(module)) {
return createNotificationPanel(module);
}
}
catch (ProcessCanceledException ignore) {}
catch (IndexNotReadyException ignore) {}
return null;
}
@NotNull
private static EditorNotificationPanel createNotificationPanel(@NotNull final Module module) {
EditorNotificationPanel panel = new EditorNotificationPanel();
panel.setText("Kotlin SDK is not configured for module \"" + module.getName() + "\"");
panel.createActionLabel("Configure Kotlin SDK", new Runnable() {
@Override
public void run() {
AddFrameworkSupportDialog dialog = AddFrameworkSupportDialog.createDialog(module);
if (dialog != null) {
dialog.show();
}
}
});
return panel;
}
}
@@ -1,58 +0,0 @@
/*
* 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.roots.libraries.LibraryPresentationProvider;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.JetIcons;
import javax.swing.*;
import java.io.File;
import java.util.List;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinSdkPresentationProvider extends LibraryPresentationProvider<KotlinSdkProperties> {
public KotlinSdkPresentationProvider() {
super(KotlinSdkUtil.getKotlinSdkLibraryKind());
}
@NotNull
@Override
public Icon getIcon() {
return JetIcons.SMALL_LOGO;
}
@NotNull
@Override
public String getDescription(@NotNull KotlinSdkProperties properties) {
return KotlinSdkUtil.getSDKName(properties.getSdkHome(), properties.getVersion());
}
@Nullable
@Override
public KotlinSdkProperties detect(@NotNull List<VirtualFile> classesRoots) {
File sdkHome = KotlinSdkUtil.detectSDKHome(classesRoots);
if (sdkHome == null) return null;
String sdkVersion = KotlinSdkUtil.getSDKVersion(sdkHome);
return sdkVersion == null ? null : new KotlinSdkProperties(sdkHome, sdkVersion);
}
}
@@ -1,77 +0,0 @@
/*
* 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.roots.libraries.LibraryProperties;
import org.jetbrains.annotations.NotNull;
import java.io.File;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinSdkProperties extends LibraryProperties<KotlinSdkProperties> {
@NotNull private File mySdkHome;
@NotNull private String myVersion;
public KotlinSdkProperties(@NotNull File sdkHome, @NotNull String version) {
mySdkHome = sdkHome;
myVersion = version;
}
@NotNull
public File getSdkHome() {
return mySdkHome;
}
@NotNull
public String getVersion() {
return myVersion;
}
@Override
public KotlinSdkProperties getState() {
return this;
}
@Override
public void loadState(@NotNull KotlinSdkProperties state) {
mySdkHome = state.mySdkHome;
myVersion = state.myVersion;
}
@Override
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() {
int result = mySdkHome.hashCode();
result = 31 * result + myVersion.hashCode();
return result;
}
}
@@ -1,205 +0,0 @@
/*
* 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.module.Module;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.PersistentLibraryKind;
import com.intellij.openapi.util.io.FileUtil;
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;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinSdkUtil {
@NotNull private static PersistentLibraryKind<KotlinSdkProperties> KOTLIN_SDK_KIND =
new PersistentLibraryKind<KotlinSdkProperties>("KotlinSDK", false) {
@NotNull
@Override
public KotlinSdkProperties createDefaultProperties() {
return new KotlinSdkProperties(new File(""), "");
}
};
@NotNull private static String[] KOTLIN_COMPILER_JAR_ENTRY_NAMES = {
"org/jetbrains/jet/cli/KotlinCompiler.class",
"org/jetbrains/jet/cli/jvm/K2JVMCompiler.class"
};
private KotlinSdkUtil() {}
public static boolean isSDKHome(@Nullable VirtualFile dir) {
return dir != null && isSDKHome(new File(dir.getPath()));
}
private static boolean isSDKHome(@NotNull File dir) {
return dir.isDirectory() && isKotlinCompilerJar(PathUtil.getCompilerPath(dir));
}
@Nullable
public static String getSDKVersion(@NotNull File sdkHome) {
String buildNumber = getSDKBuildNumber(sdkHome);
if (buildNumber == null) return null;
int lastDotPos = buildNumber.lastIndexOf('.');
return lastDotPos == -1 ? buildNumber : buildNumber.substring(0, lastDotPos);
}
@Nullable
private static String getSDKBuildNumber(@NotNull File sdkHome) {
try {
return FileUtil.loadFile(new File(sdkHome, "build.txt")).trim();
}
catch (IOException e) {
try {
File compilerJar = PathUtil.getCompilerPath(sdkHome);
return compilerJar == null ? null : getJarImplementationVersion(compilerJar);
}
catch (IOException e1) {
return null;
}
}
}
@Nullable
private static String getJarImplementationVersion(@NotNull File jar) throws IOException {
JarFile jarFile = new JarFile(jar);
try {
Manifest manifest = jarFile.getManifest();
return manifest == null ? null : manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
}
finally {
jarFile.close();
}
}
@Nullable
public static File detectSDKHome(@NotNull List<VirtualFile> jars) {
for (VirtualFile jar : jars) {
jar = prepare(jar);
if (jar == null) continue;
File file = new File(jar.getPath());
if (file.getName().equals(PathUtil.KOTLIN_COMPILER_JAR) && isKotlinCompilerJar(file)) {
File sdkHome = PathUtil.getSDKHomeByCompilerPath(file);
if (sdkHome != null) {
return sdkHome;
}
}
}
return null;
}
@Nullable
private static VirtualFile prepare(@NotNull VirtualFile jar) {
if (jar.getFileSystem() instanceof JarFileSystem) {
return JarFileSystem.getInstance().getVirtualFileForJar(jar);
}
return jar;
}
public static boolean isSDKConfiguredFor(@NotNull Module module) {
return getSDKHomeFor(module) != null;
}
@Nullable
public static File getSDKHomeFor(@NotNull Module module) {
return findSDKHome(module, new HashSet<String>(), false);
}
@Nullable
public static File findSDKHome(@NotNull Module module, @NotNull Set<String> checkedModuleNames, boolean isDependency) {
checkedModuleNames.add(module.getName());
for (OrderEntry orderEntry : ModuleRootManager.getInstance(module).getOrderEntries()) {
if (orderEntry instanceof ModuleOrderEntry) {
ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)orderEntry;
Module depModule = moduleOrderEntry.getModule();
if (depModule != null && !checkedModuleNames.contains(depModule.getName()) && isAvailable(moduleOrderEntry, isDependency)) {
File sdkHome = findSDKHome(depModule, checkedModuleNames, true);
if (sdkHome != null) {
return sdkHome;
}
}
}
else if (orderEntry instanceof LibraryOrderEntry) {
LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry;
if (isAvailable(libraryOrderEntry, isDependency)) {
File sdkHome = detectSDKHome(Arrays.asList(libraryOrderEntry.getRootFiles(OrderRootType.CLASSES)));
if (sdkHome != null) {
return sdkHome;
}
}
}
}
return null;
}
private static boolean isAvailable(@NotNull ExportableOrderEntry orderEntry, boolean isDependency) {
return !isDependency || orderEntry.isExported();
}
private static boolean isKotlinCompilerJar(@Nullable File jar) {
try {
return jar != null && doIsKotlinCompilerJar(jar);
}
catch (IOException e) {
return false;
}
}
private static boolean doIsKotlinCompilerJar(@NotNull File jar) throws IOException {
JarFile jarFile = new JarFile(jar);
try {
for (String entryName : KOTLIN_COMPILER_JAR_ENTRY_NAMES) {
if (jarFile.getJarEntry(entryName) != null) {
return true;
}
}
return false;
}
finally {
jarFile.close();
}
}
public static boolean isBundledSDK(@NotNull File sdkHome) {
return sdkHome.equals(PluginPathUtil.getBundledSDKHome());
}
@NotNull
public static String getSDKName(@NotNull File sdkHome, @NotNull String version) {
return "Kotlin " + version + (isBundledSDK(sdkHome) ? " (bundled)" : "");
}
@NotNull
public static PersistentLibraryKind<KotlinSdkProperties> getKotlinSdkLibraryKind() {
return KOTLIN_SDK_KIND;
}
}
@@ -1,70 +0,0 @@
/*
* 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.util;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.sdk.KotlinSdkUtil;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
/**
* @author Maxim.Manuylov
* Date: 20.05.12
*/
public class PluginPathUtil {
private PluginPathUtil() {}
@Nullable
public static File getBundledSDKHome() {
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 Module module) {
return PathUtil.getRuntimePath(KotlinSdkUtil.getSDKHomeFor(module));
}
@Nullable
public static File getJsLibJsPath(@NotNull Module module) {
return PathUtil.getJsLibJsPath(KotlinSdkUtil.getSDKHomeFor(module));
}
@Nullable
public static File getJsLibJarPath(@NotNull Module module) {
return PathUtil.getJsLibJarPath(KotlinSdkUtil.getSDKHomeFor(module));
}
@Nullable
public static File getJdkAnnotationsPath(@NotNull Module module) {
return PathUtil.getJdkAnnotationsPath(KotlinSdkUtil.getSDKHomeFor(module));
}
}
@@ -22,19 +22,13 @@ import com.intellij.openapi.compiler.TranslatingCompiler;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
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 com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PlatformTestCase;
import jet.Function1;
import junit.framework.Assert;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.plugin.sdk.KotlinSdkDescription;
import java.io.File;
import java.io.IOException;
/**
@@ -44,18 +38,17 @@ public abstract class IDECompilerMessagingTest extends PlatformTestCase {
protected void performTest(@NotNull Function1<MessageChecker, Void> whatToExpect,
@NotNull TranslatingCompiler compiler, @NotNull String testDataPath) {
String pathToTestDir = testDataPath + "/" + getTestName(true);
final String pathToTestDir = testDataPath + "/" + getTestName(true);
VirtualFile testDir = LocalFileSystem.getInstance().findFileByPath(pathToTestDir);
Assert.assertNotNull(testDir);
VirtualFile sampleFile = LocalFileSystem.getInstance().findFileByPath(pathToTestDir + "/src/test.kt");
VirtualFile outDirectory = getOutDirectory(pathToTestDir, testDir);
String pathToSrc = pathToTestDir + "/src/";
final String pathToSrc = pathToTestDir + "/src/";
VirtualFile root = LocalFileSystem.getInstance().findFileByPath(pathToSrc);
Assert.assertNotNull(root);
MockCompileContext mockCompileContext = new MockCompileContext(myModule, outDirectory, root);
MockModuleChunk mockModuleChunk = new MockModuleChunk(myModule);
setSourceEntryForModule(root);
setKotlinSdkForModule();
assert sampleFile != null;
compile(compiler, sampleFile, mockCompileContext, mockModuleChunk);
checkMessages(whatToExpect, mockCompileContext);
@@ -87,25 +80,6 @@ public abstract class IDECompilerMessagingTest extends PlatformTestCase {
});
}
private void setKotlinSdkForModule() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel();
model.addLibraryEntry(createKotlinSdkLibrary());
model.commit();
}
});
}
@NotNull
private Library createKotlinSdkLibrary() {
NewLibraryEditor editor = new NewLibraryEditor();
editor.setName("Kotlin SDK");
KotlinSdkDescription.addSDKRoots(editor, new File("dist/kotlinc"));
return LibrariesContainerFactory.createContainer(myModule).createLibrary(editor, LibrariesContainer.LibraryLevel.GLOBAL);
}
protected abstract void checkHeader(@NotNull MessageChecker checker);
@NotNull