diff --git a/build.xml b/build.xml index 073b019b38e..f4240282d1b 100644 --- a/build.xml +++ b/build.xml @@ -498,8 +498,6 @@ - - @@ -512,6 +510,22 @@ + + + + + + + + + + + + + + + + @@ -539,11 +553,11 @@ + depends="clean,init,prepareDist,preloader,compiler,compilerSources,antTools,jdkAnnotations,androidSdkAnnotations,annotationsExt,runtime,runtime_sources,jslib,j2kConverter"/> + depends="clean,init,prepareDist,preloader,compiler_quick,antTools,jdkAnnotations,androidSdkAnnotations,annotationsExt,runtime,runtime_sources,jslib,j2kConverter"/> "); diff --git a/idea/src/org/jetbrains/jet/plugin/configuration/KotlinJavaModuleConfigurator.java b/idea/src/org/jetbrains/jet/plugin/configuration/KotlinJavaModuleConfigurator.java index cda40e567ec..4169793e8a0 100644 --- a/idea/src/org/jetbrains/jet/plugin/configuration/KotlinJavaModuleConfigurator.java +++ b/idea/src/org/jetbrains/jet/plugin/configuration/KotlinJavaModuleConfigurator.java @@ -1,11 +1,7 @@ package org.jetbrains.jet.plugin.configuration; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.vfs.VfsUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.plugin.framework.JavaRuntimeLibraryDescription; import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector; @@ -31,15 +27,14 @@ public class KotlinJavaModuleConfigurator extends KotlinWithLibraryConfigurator @NotNull @Override - protected String getJarName() { + public String getJarName() { return PathUtil.KOTLIN_JAVA_RUNTIME_JAR; } + @NotNull @Override - protected void addRootsToLibrary(@NotNull Library.ModifiableModel library, @NotNull File jarFile) { - String libraryRoot = VfsUtil.getUrlForLibraryRoot(jarFile); - library.addRoot(libraryRoot, OrderRootType.CLASSES); - library.addRoot(libraryRoot + "src", OrderRootType.SOURCES); + public String getSourcesJarName() { + return PathUtil.KOTLIN_JAVA_RUNTIME_SRC_JAR; } @NotNull @@ -86,17 +81,12 @@ public class KotlinJavaModuleConfigurator extends KotlinWithLibraryConfigurator @Override @NotNull public File getExistedJarFile() { - File result; - if (ApplicationManager.getApplication().isUnitTestMode()) { - result = PathUtil.getKotlinPathsForDistDirectory().getRuntimePath(); - } - else { - result = PathUtil.getKotlinPathsForIdeaPlugin().getRuntimePath(); - } - if (!result.exists()) { - showError("Jar file wasn't found in " + result.getPath()); - } - return result; + return assertFileExists(getKotlinPaths().getRuntimePath()); + } + + @Override + public File getExistedSourcesJarFile() { + return assertFileExists(getKotlinPaths().getRuntimeSourcesPath()); } KotlinJavaModuleConfigurator() { diff --git a/idea/src/org/jetbrains/jet/plugin/configuration/KotlinJsModuleConfigurator.java b/idea/src/org/jetbrains/jet/plugin/configuration/KotlinJsModuleConfigurator.java index 4d9ac7dc3c9..6d355ef42fd 100644 --- a/idea/src/org/jetbrains/jet/plugin/configuration/KotlinJsModuleConfigurator.java +++ b/idea/src/org/jetbrains/jet/plugin/configuration/KotlinJsModuleConfigurator.java @@ -1,11 +1,8 @@ package org.jetbrains.jet.plugin.configuration; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.vfs.VfsUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.plugin.framework.JSLibraryStdDescription; @@ -35,8 +32,8 @@ public class KotlinJsModuleConfigurator extends KotlinWithLibraryConfigurator { @Override public boolean isConfigured(@NotNull Module module) { if (KotlinFrameworkDetector.isJsKotlinModule(module)) { - String pathFromLibrary = getPathToJarFromLibrary(module.getProject()); - return pathFromLibrary != null && getJarFile(pathFromLibrary).exists(); + String pathFromLibrary = getPathFromLibrary(module.getProject(), OrderRootType.CLASSES); + return pathFromLibrary != null && getFileInDir(getJarName(), pathFromLibrary).exists(); } return false; } @@ -49,15 +46,14 @@ public class KotlinJsModuleConfigurator extends KotlinWithLibraryConfigurator { @NotNull @Override - protected String getJarName() { + public String getJarName() { return PathUtil.JS_LIB_JAR_NAME; } + @NotNull @Override - protected void addRootsToLibrary(@NotNull Library.ModifiableModel library, @NotNull File jarFile) { - String libraryRoot = VfsUtil.getUrlForLibraryRoot(jarFile); - library.addRoot(libraryRoot, OrderRootType.CLASSES); - library.addRoot(libraryRoot, OrderRootType.SOURCES); + protected String getSourcesJarName() { + return PathUtil.JS_LIB_JAR_NAME; } @NotNull @@ -69,17 +65,12 @@ public class KotlinJsModuleConfigurator extends KotlinWithLibraryConfigurator { @NotNull @Override public File getExistedJarFile() { - File result; - if (ApplicationManager.getApplication().isUnitTestMode()) { - result = PathUtil.getKotlinPathsForDistDirectory().getJsLibJarPath(); - } - else { - result = PathUtil.getKotlinPathsForIdeaPlugin().getJsLibJarPath(); - } - if (!result.exists()) { - showError("Jar file wasn't found in " + result.getPath()); - } - return result; + return assertFileExists(getKotlinPaths().getJsLibJarPath()); + } + + @Override + protected File getExistedSourcesJarFile() { + return getExistedJarFile(); } @Override @@ -113,23 +104,12 @@ public class KotlinJsModuleConfigurator extends KotlinWithLibraryConfigurator { } public static boolean isJsFilePresent(@NotNull String dir) { - String runtimeJarFileName = dir + "/" + PathUtil.JS_LIB_JAR_NAME; - return new File(runtimeJarFileName).exists(); + return new File(dir + "/" + PathUtil.JS_LIB_JAR_NAME).exists(); } @NotNull public File getJsFile() { - File result; - if (ApplicationManager.getApplication().isUnitTestMode()) { - result = PathUtil.getKotlinPathsForDistDirectory().getJsLibJsPath(); - } - else { - result = PathUtil.getKotlinPathsForIdeaPlugin().getJsLibJsPath(); - } - if (!result.exists()) { - showError("Jar file wasn't found in " + result.getPath()); - } - return result; + return assertFileExists(getKotlinPaths().getJsLibJsPath()); } private static boolean needToChooseJsFilePath(@NotNull Project project) { diff --git a/idea/src/org/jetbrains/jet/plugin/configuration/KotlinWithLibraryConfigurator.java b/idea/src/org/jetbrains/jet/plugin/configuration/KotlinWithLibraryConfigurator.java index 7d3d13de981..f9e01f3a755 100644 --- a/idea/src/org/jetbrains/jet/plugin/configuration/KotlinWithLibraryConfigurator.java +++ b/idea/src/org/jetbrains/jet/plugin/configuration/KotlinWithLibraryConfigurator.java @@ -20,6 +20,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.plugin.JetPluginUtil; import org.jetbrains.jet.plugin.framework.ui.FileUIUtils; +import org.jetbrains.jet.utils.KotlinPaths; +import org.jetbrains.jet.utils.PathUtil; import java.io.File; @@ -33,29 +35,46 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf @NotNull protected abstract String getJarName(); + @NotNull + protected abstract String getSourcesJarName(); + @NotNull protected abstract String getMessageForOverrideDialog(); @NotNull protected abstract File getExistedJarFile(); - protected abstract void addRootsToLibrary(@NotNull Library.ModifiableModel library, @NotNull File jarFile); + protected abstract File getExistedSourcesJarFile(); @Override public boolean isApplicable(@NotNull Module module) { - return !JetPluginUtil.isAndroidGradleModule(module) && !JetPluginUtil.isMavenModule(module) && !JetPluginUtil.isGradleModule(module); - } - - public boolean isJarPresent(@NotNull String dir) { - return getJarInDir(dir).exists(); - } - - public File getJarInDir(@NotNull String dir) { - String runtimeJarFileName = dir + "/" + getJarName(); - return new File(runtimeJarFileName); + return !JetPluginUtil.isAndroidGradleModule(module) && + !JetPluginUtil.isMavenModule(module) && + !JetPluginUtil.isGradleModule(module); } protected void configureModuleWithLibrary( + @NotNull Module module, + @NotNull String defaultPath, + @Nullable String pathFromDialog + ) { + Project project = module.getProject(); + + FileState runtimeState = getJarState(project, getJarName(), OrderRootType.CLASSES, defaultPath, pathFromDialog); + LibraryState libraryState = getLibraryState(project); + String dirToCopyJar = getPathToCopyFileTo(project, OrderRootType.CLASSES, defaultPath, pathFromDialog); + + configureModuleWithLibraryClasses(module, libraryState, runtimeState, dirToCopyJar); + + Library library = getKotlinLibrary(project); + assert library != null : "Kotlin library should exists when adding sources root"; + FileState sourcesState = getJarState(project, getSourcesJarName(), OrderRootType.SOURCES, defaultPath, pathFromDialog); + String dirToCopySourcesJar = getPathToCopyFileTo(project, OrderRootType.SOURCES, defaultPath, pathFromDialog); + + configureModuleWithLibrarySources(library, sourcesState, dirToCopySourcesJar); + } + + protected void configureModuleWithLibraryClasses( @NotNull Module module, @NotNull LibraryState libraryState, @NotNull FileState jarState, @@ -82,7 +101,7 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf case NON_CONFIGURED_LIBRARY: switch (jarState) { case EXISTS: { - addJarToExistedLibrary(project, getJarFile(dirToCopyJarTo)); + addJarToExistedLibrary(project, getFileInDir(getJarName(), dirToCopyJarTo)); break; } case COPY: { @@ -99,7 +118,7 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf case NEW_LIBRARY: switch (jarState) { case EXISTS: { - addJarToNewLibrary(project, getJarFile(dirToCopyJarTo)); + addJarToNewLibrary(project, getFileInDir(getJarName(), dirToCopyJarTo)); break; } case COPY: { @@ -117,21 +136,66 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf addLibraryToModuleIfNeeded(module); } - private void addLibraryToModuleIfNeeded(Module module) { - if (getKotlinLibrary(module) == null) { - Library library = getKotlinLibrary(module.getProject()); - assert library != null : "Kotlin project library should exists"; - ModuleRootModificationUtil.addDependency(module, library); - showInfoNotification(library.getName() + " library was added to module " + module.getName()); + protected void configureModuleWithLibrarySources( + @NotNull Library library, + @NotNull FileState jarState, + @Nullable String dirToCopyJarTo + ) { + switch (jarState) { + case EXISTS: { + if (dirToCopyJarTo != null) { + addSourcesToLibraryIfNeeded(library, getFileInDir(getSourcesJarName(), dirToCopyJarTo)); + } + break; + } + case COPY: { + assert dirToCopyJarTo != null : "Path to copy should be non-null"; + File file = copyFileToDir(getExistedSourcesJarFile(), dirToCopyJarTo); + addSourcesToLibraryIfNeeded(library, file); + break; + } + case DO_NOT_COPY: { + addSourcesToLibraryIfNeeded(library, getExistedSourcesJarFile()); + break; + } } } + @NotNull + public static File getFileInDir(@NotNull String fileName, @NotNull String dirToJar) { + return new File(dirToJar + "/" + fileName); + } + @Nullable - protected String getPathToJarFromLibrary(Project project) { + public Library getKotlinLibrary(@NotNull Project project) { + LibrariesContainer librariesContainer = LibrariesContainerFactory.createContainer(project); + for (Library library : librariesContainer.getLibraries(LibrariesContainer.LibraryLevel.PROJECT)) { + if (isKotlinLibrary(library)) { + return library; + } + } + for (Library library : librariesContainer.getLibraries(LibrariesContainer.LibraryLevel.GLOBAL)) { + if (isKotlinLibrary(library)) { + return library; + } + } + return null; + } + + public File copyFileToDir(@NotNull File file, @NotNull String toDir) { + File copy = FileUIUtils.copyWithOverwriteDialog(getMessageForOverrideDialog(), toDir, file); + if (copy != null) { + showInfoNotification(file.getName() + " was copied to " + toDir); + } + return copy; + } + + @Nullable + protected String getPathFromLibrary(@NotNull Project project, @NotNull OrderRootType type) { Library library = getKotlinLibrary(project); if (library == null) return null; - String[] libraryFiles = library.getUrls(OrderRootType.CLASSES); + String[] libraryFiles = library.getUrls(type); if (libraryFiles.length < 1) return null; String pathToJarInLib = VfsUtilCore.urlToPath(libraryFiles[0]); @@ -145,36 +209,49 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf return parentDir; } - @NotNull - protected File getJarFile(@NotNull String dirToJar) { - return new File(dirToJar + "/" + getJarName()); - } + private static void addSourcesToLibraryIfNeeded(@NotNull Library library, @NotNull File file) { + String[] librarySourceRoots = library.getUrls(OrderRootType.SOURCES); + for (String sourceRoot : librarySourceRoots) { + if (sourceRoot.equals(VfsUtil.getUrlForLibraryRoot(file))) return; + } - protected void configureModuleWithLibrary( - @NotNull Module module, - @NotNull String defaultPath, - @Nullable String pathFromDialog - ) { - Project project = module.getProject(); - - FileState runtimeState = getJarState(project, defaultPath, pathFromDialog); - LibraryState libraryState = getLibraryState(project); - String dirToCopyJar = getPathToCopyFileTo(project, defaultPath, pathFromDialog); - - configureModuleWithLibrary(module, libraryState, runtimeState, dirToCopyJar); - } - - private void addJarToExistedLibrary(@NotNull Project project, @NotNull File jarFile) { - Library library = getKotlinLibrary(project); - assert library != null : "Kotlin library should present, instead createNewLibrary should be invoked"; final Library.ModifiableModel model = library.getModifiableModel(); - addRootsToLibrary(model, jarFile); + model.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.SOURCES); + ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { model.commit(); } }); + + showInfoNotification(library.getName() + " library was configured"); + } + + private void addLibraryToModuleIfNeeded(Module module) { + if (getKotlinLibrary(module) == null) { + Library library = getKotlinLibrary(module.getProject()); + assert library != null : "Kotlin project library should exists"; + + ModuleRootModificationUtil.addDependency(module, library); + showInfoNotification(library.getName() + " library was added to module " + module.getName()); + } + } + + private void addJarToExistedLibrary(@NotNull Project project, @NotNull File jarFile) { + Library library = getKotlinLibrary(project); + assert library != null : "Kotlin library should present, instead createNewLibrary should be invoked"; + + final Library.ModifiableModel model = library.getModifiableModel(); + model.addRoot(VfsUtil.getUrlForLibraryRoot(jarFile), OrderRootType.CLASSES); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + model.commit(); + } + }); + showInfoNotification(library.getName() + " library was configured"); } @@ -189,7 +266,7 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf public void run() { library.set(table.createLibrary(getLibraryName())); Library.ModifiableModel model = library.get().getModifiableModel(); - addRootsToLibrary(model, jarFile); + model.addRoot(VfsUtil.getUrlForLibraryRoot(jarFile), OrderRootType.CLASSES); model.commit(); } }); @@ -223,41 +300,17 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf return result.get(); } - @Nullable - private Library getKotlinLibrary(@NotNull Project project) { - LibrariesContainer librariesContainer = LibrariesContainerFactory.createContainer(project); - for (Library library : librariesContainer.getLibraries(LibrariesContainer.LibraryLevel.PROJECT)) { - if (isKotlinLibrary(library)) { - return library; - } - } - for (Library library : librariesContainer.getLibraries(LibrariesContainer.LibraryLevel.GLOBAL)) { - if (isKotlinLibrary(library)) { - return library; - } - } - return null; - } - private boolean isKotlinLibrary(@NotNull Library library) { return getLibraryName().equals(library.getName()); } - public File copyJarToDir(@NotNull String toDir) { + private File copyJarToDir(@NotNull String toDir) { return copyFileToDir(getExistedJarFile(), toDir); } - public File copyFileToDir(@NotNull File file, @NotNull String toDir) { - File copy = FileUIUtils.copyWithOverwriteDialog(getMessageForOverrideDialog(), toDir, file); - if (copy != null) { - showInfoNotification(file.getName() + " was copied to " + toDir); - } - return copy; - } - protected boolean needToChooseJarPath(@NotNull Project project) { String defaultPath = getDefaultPathToJarFile(project); - return !isProjectLibraryPresent(project) && !isJarPresent(defaultPath); + return !isProjectLibraryPresent(project) && !getFileInDir(getJarName(), defaultPath).exists(); } protected static String getDefaultPathToJarFile(@NotNull Project project) { @@ -294,16 +347,18 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf @NotNull protected FileState getJarState( @NotNull Project project, + @NotNull String jarName, + @NotNull OrderRootType jarType, @NotNull String defaultPath, @Nullable String pathFromDialog ) { - String pathFormLibrary = getPathToJarFromLibrary(project); - if (isJarPresent(defaultPath) || - (pathFromDialog != null && isJarPresent(pathFromDialog)) || - (pathFormLibrary != null && getJarFile(pathFormLibrary).exists())) { - return FileState.EXISTS; + String pathFromLibrary = getPathFromLibrary(project, jarType); + if (getFileInDir(jarName, defaultPath).exists() || + (pathFromDialog != null && getFileInDir(jarName, pathFromDialog).exists()) || + (pathFromLibrary != null && getFileInDir(jarName, pathFromLibrary).exists())) { + return FileState.EXISTS; } - else if (pathFormLibrary != null) { + else if (pathFromLibrary != null) { return FileState.COPY; } else if (pathFromDialog == null) { @@ -314,22 +369,36 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf } } + protected static KotlinPaths getKotlinPaths() { + return ApplicationManager.getApplication().isUnitTestMode() + ? PathUtil.getKotlinPathsForDistDirectory() + : PathUtil.getKotlinPathsForIdeaPlugin(); + } + @NotNull private String getPathToCopyFileTo( @NotNull Project project, + @NotNull OrderRootType jarType, @NotNull String defaultDir, @Nullable String pathFromDialog ) { if (pathFromDialog != null) { return pathFromDialog; } - String pathFormLibrary = getPathToJarFromLibrary(project); - if (pathFormLibrary != null) { - return pathFormLibrary; + String pathFromLibrary = getPathFromLibrary(project, jarType); + if (pathFromLibrary != null) { + return pathFromLibrary; } return defaultDir; } + protected File assertFileExists(@NotNull File file) { + if (!file.exists()) { + showError("Couldn't find file: " + file.getPath()); + } + return file; + } + KotlinWithLibraryConfigurator() { } } diff --git a/idea/src/org/jetbrains/jet/plugin/framework/JSLibraryStdDescription.java b/idea/src/org/jetbrains/jet/plugin/framework/JSLibraryStdDescription.java index a5c7f84c764..555daf16fa3 100644 --- a/idea/src/org/jetbrains/jet/plugin/framework/JSLibraryStdDescription.java +++ b/idea/src/org/jetbrains/jet/plugin/framework/JSLibraryStdDescription.java @@ -27,10 +27,8 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.plugin.configuration.ConfigureKotlinInProjectUtils; import org.jetbrains.jet.plugin.configuration.KotlinJsModuleConfigurator; import org.jetbrains.jet.plugin.framework.ui.CreateJavaScriptLibraryDialog; -import org.jetbrains.jet.plugin.framework.ui.FileUIUtils; import javax.swing.*; import java.io.File; @@ -38,6 +36,8 @@ import java.util.Set; import static org.jetbrains.jet.plugin.configuration.ConfigureKotlinInProjectUtils.getConfiguratorByName; import static org.jetbrains.jet.plugin.configuration.KotlinJsModuleConfigurator.NAME; +import static org.jetbrains.jet.plugin.configuration.KotlinJsModuleConfigurator.isJsFilePresent; +import static org.jetbrains.jet.plugin.configuration.KotlinWithLibraryConfigurator.getFileInDir; import static org.jetbrains.jet.plugin.framework.ui.FileUIUtils.createRelativePath; public class JSLibraryStdDescription extends CustomLibraryDescription { @@ -62,11 +62,11 @@ public class JSLibraryStdDescription extends CustomLibraryDescription { String defaultPathToJsFileDir = createRelativePath(null, contextDirectory, "script"); String defaultPathToJarFileDir = createRelativePath(null, contextDirectory, "lib"); - boolean jsFilePresent = KotlinJsModuleConfigurator.isJsFilePresent(defaultPathToJsFileDir); - boolean jarFilePresent = configurator.isJarPresent(defaultPathToJarFileDir); + boolean jsFilePresent = isJsFilePresent(defaultPathToJsFileDir); + boolean jarFilePresent = getFileInDir(configurator.getJarName(), defaultPathToJarFileDir).exists(); if (jarFilePresent && jsFilePresent) { - return createConfiguration(configurator.getJarInDir(defaultPathToJarFileDir)); + return createConfiguration(getFileInDir(configurator.getJarName(), defaultPathToJarFileDir)); } CreateJavaScriptLibraryDialog dialog = @@ -81,15 +81,16 @@ public class JSLibraryStdDescription extends CustomLibraryDescription { } if (jarFilePresent) { - return createConfiguration(configurator.getJarInDir(defaultPathToJarFileDir)); + return createConfiguration(getFileInDir(configurator.getJarName(), defaultPathToJarFileDir)); } else { String copyIntoPath = dialog.getCopyLibraryIntoPath(); + File existedJarFile = configurator.getExistedJarFile(); if (copyIntoPath != null) { - return createConfiguration(configurator.copyJarToDir(copyIntoPath)); + return createConfiguration(configurator.copyFileToDir(existedJarFile, copyIntoPath)); } else { - return createConfiguration(configurator.getExistedJarFile()); + return createConfiguration(existedJarFile); } } } diff --git a/idea/src/org/jetbrains/jet/plugin/framework/JavaRuntimeLibraryDescription.java b/idea/src/org/jetbrains/jet/plugin/framework/JavaRuntimeLibraryDescription.java index 7ca6ed431ac..6f4485b3638 100644 --- a/idea/src/org/jetbrains/jet/plugin/framework/JavaRuntimeLibraryDescription.java +++ b/idea/src/org/jetbrains/jet/plugin/framework/JavaRuntimeLibraryDescription.java @@ -23,7 +23,6 @@ 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.ui.Messages; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -32,13 +31,13 @@ import org.jetbrains.jet.plugin.configuration.ConfigureKotlinInProjectUtils; import org.jetbrains.jet.plugin.configuration.KotlinJavaModuleConfigurator; import org.jetbrains.jet.plugin.framework.ui.CreateJavaLibraryDialog; import org.jetbrains.jet.plugin.framework.ui.FileUIUtils; -import org.jetbrains.jet.utils.KotlinPaths; -import org.jetbrains.jet.utils.PathUtil; import javax.swing.*; import java.io.File; import java.util.Set; +import static org.jetbrains.jet.plugin.configuration.KotlinWithLibraryConfigurator.getFileInDir; + public class JavaRuntimeLibraryDescription extends CustomLibraryDescription { public static final LibraryKind KOTLIN_JAVA_RUNTIME_KIND = LibraryKind.create("kotlin-java-runtime"); public static final String LIBRARY_NAME = "KotlinJavaRuntime"; @@ -61,11 +60,15 @@ public class JavaRuntimeLibraryDescription extends CustomLibraryDescription { String defaultPathToJarFile = FileUIUtils.createRelativePath(null, contextDirectory, "lib"); - boolean jarFilePresent = configurator.isJarPresent(defaultPathToJarFile); + boolean jarFilePresent = getFileInDir(configurator.getJarName(), defaultPathToJarFile).exists(); File libraryFile; + File librarySrcFile; if (jarFilePresent) { - libraryFile = configurator.getJarInDir(defaultPathToJarFile); + libraryFile = getFileInDir(configurator.getJarName(), defaultPathToJarFile); + File sourcesJar = getFileInDir(configurator.getSourcesJarName(), defaultPathToJarFile); + librarySrcFile = sourcesJar.exists() ? sourcesJar + : configurator.copyFileToDir(configurator.getExistedSourcesJarFile(), libraryFile.getParent()); } else { CreateJavaLibraryDialog dialog = new CreateJavaLibraryDialog(defaultPathToJarFile); @@ -74,15 +77,22 @@ public class JavaRuntimeLibraryDescription extends CustomLibraryDescription { if (!dialog.isOK()) return null; String copyIntoPath = dialog.getCopyIntoPath(); - libraryFile = copyIntoPath != null ? configurator.copyJarToDir(copyIntoPath) : configurator.getExistedJarFile(); + + File existedJarFile = configurator.getExistedJarFile(); + libraryFile = copyIntoPath != null ? configurator.copyFileToDir(existedJarFile, copyIntoPath) : existedJarFile; + + File existedSourcesJarFile = configurator.getExistedSourcesJarFile(); + librarySrcFile = copyIntoPath != null ? configurator.copyFileToDir(existedSourcesJarFile, copyIntoPath) : existedSourcesJarFile; } final String libraryFileUrl = VfsUtil.getUrlForLibraryRoot(libraryFile); + final String libraryFileSrcUrl = VfsUtil.getUrlForLibraryRoot(librarySrcFile); + return new NewLibraryConfiguration(LIBRARY_NAME, getDownloadableLibraryType(), new LibraryVersionProperties()) { @Override public void addRoots(@NotNull LibraryEditor editor) { editor.addRoot(libraryFileUrl, OrderRootType.CLASSES); - editor.addRoot(libraryFileUrl + "src", OrderRootType.SOURCES); + editor.addRoot(libraryFileSrcUrl, OrderRootType.SOURCES); } }; } diff --git a/idea/src/org/jetbrains/jet/plugin/framework/JavaRuntimePresentationProvider.java b/idea/src/org/jetbrains/jet/plugin/framework/JavaRuntimePresentationProvider.java index 76d543c10a8..4bfe29dea4f 100644 --- a/idea/src/org/jetbrains/jet/plugin/framework/JavaRuntimePresentationProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/framework/JavaRuntimePresentationProvider.java @@ -69,8 +69,17 @@ public class JavaRuntimePresentationProvider extends LibraryPresentationProvider @Nullable public static VirtualFile getRuntimeJar(@NotNull List classesRoots) { + return getJarFile(classesRoots, PathUtil.KOTLIN_JAVA_RUNTIME_JAR); + } + + @Nullable + public static VirtualFile getRuntimeSrcJar(@NotNull List classesRoots) { + return getJarFile(classesRoots, PathUtil.KOTLIN_JAVA_RUNTIME_SRC_JAR); + } + + private static VirtualFile getJarFile(@NotNull List classesRoots, @NotNull String jarName) { for (VirtualFile root : classesRoots) { - if (root.getName().equals(PathUtil.KOTLIN_JAVA_RUNTIME_JAR)) { + if (root.getName().equals(jarName)) { return root; } } @@ -82,4 +91,9 @@ public class JavaRuntimePresentationProvider extends LibraryPresentationProvider public static VirtualFile getRuntimeJar(@NotNull Library library) { return getRuntimeJar(Arrays.asList(library.getFiles(OrderRootType.CLASSES))); } + + @Nullable + public static VirtualFile getRuntimeSrcJar(@NotNull Library library) { + return getRuntimeSrcJar(Arrays.asList(library.getFiles(OrderRootType.SOURCES))); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/versions/KotlinRuntimeLibraryUtil.java b/idea/src/org/jetbrains/jet/plugin/versions/KotlinRuntimeLibraryUtil.java index 9dc4016221b..2c36675b5f7 100644 --- a/idea/src/org/jetbrains/jet/plugin/versions/KotlinRuntimeLibraryUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/versions/KotlinRuntimeLibraryUtil.java @@ -27,7 +27,9 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkModificator; import com.intellij.openapi.roots.AnnotationOrderRootType; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; @@ -46,6 +48,9 @@ import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.plugin.configuration.ConfigureKotlinInProjectUtils; +import org.jetbrains.jet.plugin.configuration.KotlinJavaModuleConfigurator; +import org.jetbrains.jet.utils.KotlinPaths; import org.jetbrains.jet.utils.PathUtil; import java.io.File; @@ -56,6 +61,8 @@ import java.util.Set; import static com.intellij.util.PathUtil.getLocalFile; import static com.intellij.util.PathUtil.getLocalPath; +import static org.jetbrains.jet.plugin.versions.OutdatedKotlinRuntimeNotification.showRuntimeJarNotFoundDialog; + public class KotlinRuntimeLibraryUtil { private KotlinRuntimeLibraryUtil() {} @@ -153,24 +160,58 @@ public class KotlinRuntimeLibraryUtil { return null; } - public static void updateRuntime(@NotNull final Project project, @NotNull final Runnable jarNotFoundHandler) { + public static void updateRuntime(@NotNull final Project project) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - File runtimePath = PathUtil.getKotlinPathsForIdeaPlugin().getRuntimePath(); - if (!runtimePath.exists()) { - jarNotFoundHandler.run(); - return; - } - - VirtualFile localJar = getLocalKotlinRuntimeJar(project); - assert localJar != null; - - replaceFile(runtimePath, localJar); + updateJar(project, LibraryJarDescriptor.RUNTIME_JAR); + updateJar(project, LibraryJarDescriptor.RUNTIME_SRC_JAR); } }); } + private static void updateJar(@NotNull Project project, @NotNull LibraryJarDescriptor libraryJarDescriptor) { + KotlinPaths paths = PathUtil.getKotlinPathsForIdeaPlugin(); + File runtimePath = null; + switch (libraryJarDescriptor) { + case RUNTIME_JAR: runtimePath = paths.getRuntimePath(); break; + case RUNTIME_SRC_JAR: runtimePath = paths.getRuntimeSourcesPath(); break; + } + + if (!runtimePath.exists()) { + showRuntimeJarNotFoundDialog(project, libraryJarDescriptor.jarName).run(); + return; + } + + VirtualFile jar = null; + switch (libraryJarDescriptor) { + case RUNTIME_JAR: jar = getKotlinRuntimeJar(project); break; + case RUNTIME_SRC_JAR: jar = getKotlinRuntimeSourcesJar(project); break; + } + + if (jar == null && !libraryJarDescriptor.shouldExists) { + return; + } + + VirtualFile localJar = getLocalJar(jar); + assert localJar != null; + + replaceFile(runtimePath, localJar); + } + + private enum LibraryJarDescriptor { + RUNTIME_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_JAR, true), + RUNTIME_SRC_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_SRC_JAR, false); + + @NotNull public final String jarName; + private final boolean shouldExists; + + LibraryJarDescriptor(@NotNull String jarName, boolean shouldExists) { + this.jarName = jarName; + this.shouldExists = shouldExists; + } + } + @Nullable private static VirtualFile getKotlinRuntimeJar(@NotNull Project project) { PsiClass markerClass = getKotlinRuntimeMarkerClass(ProjectScope.getAllScope(project)); @@ -183,9 +224,28 @@ public class KotlinRuntimeLibraryUtil { return projectFileIndex.getClassRootForFile(virtualFile); } + @Nullable + private static VirtualFile getKotlinRuntimeSourcesJar(@NotNull Project project) { + KotlinJavaModuleConfigurator configurator = (KotlinJavaModuleConfigurator) + ConfigureKotlinInProjectUtils.getConfiguratorByName(KotlinJavaModuleConfigurator.NAME); + assert configurator != null : "Configurator with given name doesn't exists: " + KotlinJavaModuleConfigurator.NAME; + + Library kotlinLibrary = configurator.getKotlinLibrary(project); + if (kotlinLibrary == null) return null; + + VirtualFile[] kotlinSourceFiles = kotlinLibrary.getFiles(OrderRootType.SOURCES); + if (kotlinSourceFiles.length < 1) return null; + + return kotlinSourceFiles[0]; + } + @Nullable public static VirtualFile getLocalKotlinRuntimeJar(@NotNull Project project) { - VirtualFile kotlinRuntimeJar = getKotlinRuntimeJar(project); + return getLocalJar(getKotlinRuntimeJar(project)); + } + + @Nullable + private static VirtualFile getLocalJar(@Nullable VirtualFile kotlinRuntimeJar) { if (kotlinRuntimeJar == null) return null; VirtualFile localJarFile = JarFileSystem.getInstance().getVirtualFileForJar(kotlinRuntimeJar); diff --git a/idea/src/org/jetbrains/jet/plugin/versions/OutdatedKotlinRuntimeNotification.java b/idea/src/org/jetbrains/jet/plugin/versions/OutdatedKotlinRuntimeNotification.java index 5822cc5587c..9c76957eab6 100644 --- a/idea/src/org/jetbrains/jet/plugin/versions/OutdatedKotlinRuntimeNotification.java +++ b/idea/src/org/jetbrains/jet/plugin/versions/OutdatedKotlinRuntimeNotification.java @@ -134,7 +134,7 @@ public class OutdatedKotlinRuntimeNotification extends AbstractProjectComponent public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if ("update".equals(event.getDescription())) { - updateKotlinLibraries(outdatedLibraries, showRuntimeJarNotFoundDialog(myProject)); + updateKotlinLibraries(outdatedLibraries); } else if ("ignore".equals(event.getDescription())) { PropertiesComponent.getInstance(myProject).setValue(SUPPRESSED_PROPERTY_NAME, pluginVersion); @@ -160,10 +160,10 @@ public class OutdatedKotlinRuntimeNotification extends AbstractProjectComponent }); } - private static void updateKotlinLibraries(Collection libraries, @NotNull Runnable jarNotFoundHandler) { + private void updateKotlinLibraries(Collection libraries) { File runtimePath = PathUtil.getKotlinPathsForIdeaPlugin().getRuntimePath(); if (!runtimePath.exists()) { - jarNotFoundHandler.run(); + showRuntimeJarNotFoundDialog(myProject, PathUtil.KOTLIN_JAVA_RUNTIME_JAR).run(); return; } @@ -173,6 +173,16 @@ public class OutdatedKotlinRuntimeNotification extends AbstractProjectComponent libraryJar != null : "Only java runtime libraries are expected"; KotlinRuntimeLibraryUtil.replaceFile(runtimePath, libraryJar); + + VirtualFile libraryJarSrc = JavaRuntimePresentationProvider.getRuntimeSrcJar(library); + if (libraryJarSrc != null) { + File runtimeSrcPath = PathUtil.getKotlinPathsForIdeaPlugin().getRuntimeSourcesPath(); + if (!runtimeSrcPath.exists()) { + showRuntimeJarNotFoundDialog(myProject, PathUtil.KOTLIN_JAVA_RUNTIME_SRC_JAR).run(); + return; + } + KotlinRuntimeLibraryUtil.replaceFile(runtimeSrcPath, libraryJarSrc); + } } } @@ -225,12 +235,12 @@ public class OutdatedKotlinRuntimeNotification extends AbstractProjectComponent } @NotNull - public static Runnable showRuntimeJarNotFoundDialog(@NotNull final Project project) { + public static Runnable showRuntimeJarNotFoundDialog(@NotNull final Project project, final @NotNull String jarName) { return new Runnable() { @Override public void run() { Messages.showErrorDialog(project, - "kotlin-runtime.jar is not found. Make sure plugin is properly installed.", + jarName + " is not found. Make sure plugin is properly installed.", "No Runtime Found"); } }; diff --git a/idea/src/org/jetbrains/jet/plugin/versions/UnsupportedAbiVersionNotificationPanelProvider.java b/idea/src/org/jetbrains/jet/plugin/versions/UnsupportedAbiVersionNotificationPanelProvider.java index 1f7f8d6839e..b4ba7bcf91d 100644 --- a/idea/src/org/jetbrains/jet/plugin/versions/UnsupportedAbiVersionNotificationPanelProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/versions/UnsupportedAbiVersionNotificationPanelProvider.java @@ -104,8 +104,7 @@ public class UnsupportedAbiVersionNotificationPanelProvider extends EditorNotifi answer.createActionLabel("Update " + kotlinRuntimeJarName, new Runnable() { @Override public void run() { - KotlinRuntimeLibraryUtil.updateRuntime(project, - OutdatedKotlinRuntimeNotification.showRuntimeJarNotFoundDialog(project)); + KotlinRuntimeLibraryUtil.updateRuntime(project); } }); if (otherBadRootsCount > 0) { diff --git a/idea/tests/org/jetbrains/jet/plugin/configuration/ConfigureKotlinTest.java b/idea/tests/org/jetbrains/jet/plugin/configuration/ConfigureKotlinTest.java index 340b30a3cde..ef3236346d9 100644 --- a/idea/tests/org/jetbrains/jet/plugin/configuration/ConfigureKotlinTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/configuration/ConfigureKotlinTest.java @@ -136,7 +136,7 @@ public class ConfigureKotlinTest extends PlatformTestCase { ) { for (Module module : modules) { String pathToJar = getPathToJar(runtimeState, jarFromDist, jarFromTemp); - configurator.configureModuleWithLibrary(module, libraryState, runtimeState, pathToJar); + configurator.configureModuleWithLibraryClasses(module, libraryState, runtimeState, pathToJar); } }