diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPaths.java b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPaths.java index 643c9f79123..191bdf4ea09 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPaths.java +++ b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPaths.java @@ -30,6 +30,9 @@ public interface KotlinPaths { @NotNull File getRuntimePath(); + @NotNull + File getReflectPath(); + @NotNull File getRuntimeSourcesPath(); diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPathsFromHomeDir.java b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPathsFromHomeDir.java index 898efdd7fe6..c30ec18086a 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPathsFromHomeDir.java +++ b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPathsFromHomeDir.java @@ -46,6 +46,12 @@ public class KotlinPathsFromHomeDir implements KotlinPaths { return getLibraryFile(PathUtil.KOTLIN_JAVA_RUNTIME_JAR); } + @NotNull + @Override + public File getReflectPath() { + return getLibraryFile(PathUtil.KOTLIN_JAVA_REFLECT_JAR); + } + @NotNull @Override public File getRuntimeSourcesPath() { diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/PathUtil.java b/compiler/util/src/org/jetbrains/kotlin/utils/PathUtil.java index 83e2236c45e..2c18b341340 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/PathUtil.java +++ b/compiler/util/src/org/jetbrains/kotlin/utils/PathUtil.java @@ -36,6 +36,7 @@ public class PathUtil { public static final String JDK_ANNOTATIONS_JAR = "kotlin-jdk-annotations.jar"; public static final String ANDROID_SDK_ANNOTATIONS_JAR = "kotlin-android-sdk-annotations.jar"; public static final String KOTLIN_JAVA_RUNTIME_JAR = "kotlin-runtime.jar"; + public static final String KOTLIN_JAVA_REFLECT_JAR = "kotlin-reflect.jar"; public static final String KOTLIN_JAVA_RUNTIME_SRC_JAR = "kotlin-runtime-sources.jar"; public static final String HOME_FOLDER_NAME = "kotlinc"; diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJavaModuleConfigurator.java b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJavaModuleConfigurator.java index b1464e07c9d..a1073aaa475 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJavaModuleConfigurator.java +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJavaModuleConfigurator.java @@ -90,6 +90,7 @@ public class KotlinJavaModuleConfigurator extends KotlinWithLibraryConfigurator KotlinPaths paths = PathUtil.getKotlinPathsForIdeaPlugin(); return new RuntimeLibraryFiles( assertFileExists(paths.getRuntimePath()), + assertFileExists(paths.getReflectPath()), assertFileExists(paths.getRuntimeSourcesPath()) ); } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.java b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.java index cc503ed0492..4ec8eb8d975 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.java +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.java @@ -80,8 +80,9 @@ public class KotlinJsModuleConfigurator extends KotlinWithLibraryConfigurator { public RuntimeLibraryFiles getExistingJarFiles() { KotlinPaths paths = PathUtil.getKotlinPathsForIdeaPlugin(); return new RuntimeLibraryFiles( - paths.getJsStdLibJarPath(), - paths.getJsStdLibSrcJarPath() + assertFileExists(paths.getJsStdLibJarPath()), + null, + assertFileExists(paths.getJsStdLibSrcJarPath()) ); } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.java b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.java index d654b3e43ad..00b6b7ef46b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.java +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.java @@ -32,6 +32,7 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Processor; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.idea.JetPluginUtil; @@ -136,6 +137,7 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf Project project = module.getProject(); RuntimeLibraryFiles files = getExistingJarFiles(); File runtimeJar = files.getRuntimeJar(); + File reflectJar = files.getReflectJar(); switch (libraryState) { case LIBRARY: @@ -145,6 +147,9 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf } case COPY: { copyFileToDir(runtimeJar, dirToCopyJarTo); + if (reflectJar != null) { + copyFileToDir(reflectJar, dirToCopyJarTo); + } break; } case DO_NOT_COPY: { @@ -156,16 +161,19 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf case NON_CONFIGURED_LIBRARY: switch (jarState) { case EXISTS: { - addJarToExistingLibrary(project, files.getRuntimeDestination(dirToCopyJarTo)); + addJarsToExistingLibrary( + project, files.getRuntimeDestination(dirToCopyJarTo), files.getReflectDestination(dirToCopyJarTo) + ); break; } case COPY: { - File file = copyFileToDir(runtimeJar, dirToCopyJarTo); - addJarToExistingLibrary(project, file); + addJarsToExistingLibrary( + project, copyFileToDir(runtimeJar, dirToCopyJarTo), copyFileToDir(reflectJar, dirToCopyJarTo) + ); break; } case DO_NOT_COPY: { - addJarToExistingLibrary(project, runtimeJar); + addJarsToExistingLibrary(project, runtimeJar, reflectJar); break; } } @@ -173,21 +181,23 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf case NEW_LIBRARY: switch (jarState) { case EXISTS: { - addJarToNewLibrary(project, files.getRuntimeDestination(dirToCopyJarTo)); + addJarsToNewLibrary( + project, files.getRuntimeDestination(dirToCopyJarTo), files.getReflectDestination(dirToCopyJarTo) + ); break; } case COPY: { - File file = copyFileToDir(runtimeJar, dirToCopyJarTo); - addJarToNewLibrary(project, file); + addJarsToNewLibrary(project, copyFileToDir(runtimeJar, dirToCopyJarTo), copyFileToDir(reflectJar, dirToCopyJarTo)); break; } case DO_NOT_COPY: { - addJarToNewLibrary(project, runtimeJar); + addJarsToNewLibrary(project, runtimeJar, reflectJar); break; } } break; } + addLibraryToModuleIfNeeded(module); } @@ -234,7 +244,11 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf return null; } - public File copyFileToDir(@NotNull File file, @NotNull String toDir) { + @Contract("!null, _ -> !null") + @Nullable + public File copyFileToDir(@Nullable File file, @NotNull String toDir) { + if (file == null) return null; + File copy = FileUIUtils.copyWithOverwriteDialog(getMessageForOverrideDialog(), toDir, file); if (copy != null) { showInfoNotification(file.getName() + " was copied to " + toDir); @@ -329,12 +343,15 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf return DependencyScope.COMPILE; } - private void addJarToExistingLibrary(@NotNull Project project, @NotNull File jarFile) { + private void addJarsToExistingLibrary(@NotNull Project project, @NotNull File runtimeJar, @Nullable File reflectJar) { 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); + model.addRoot(VfsUtil.getUrlForLibraryRoot(runtimeJar), OrderRootType.CLASSES); + if (reflectJar != null) { + model.addRoot(VfsUtil.getUrlForLibraryRoot(reflectJar), OrderRootType.CLASSES); + } ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override @@ -346,9 +363,10 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf showInfoNotification(library.getName() + " library was configured"); } - private void addJarToNewLibrary( + private void addJarsToNewLibrary( @NotNull Project project, - @NotNull final File jarFile + @NotNull final File runtimeJar, + @Nullable final File reflectJar ) { final LibraryTable table = LibraryTablesRegistrar.getInstance().getLibraryTable(project); final Ref library = new Ref(); @@ -357,7 +375,10 @@ public abstract class KotlinWithLibraryConfigurator implements KotlinProjectConf public void run() { library.set(table.createLibrary(getLibraryName())); Library.ModifiableModel model = library.get().getModifiableModel(); - model.addRoot(VfsUtil.getUrlForLibraryRoot(jarFile), OrderRootType.CLASSES); + model.addRoot(VfsUtil.getUrlForLibraryRoot(runtimeJar), OrderRootType.CLASSES); + if (reflectJar != null) { + model.addRoot(VfsUtil.getUrlForLibraryRoot(reflectJar), OrderRootType.CLASSES); + } model.commit(); } }); diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/RuntimeLibraryFiles.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/RuntimeLibraryFiles.kt index ba0d634743a..56b8bbc0891 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/RuntimeLibraryFiles.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/RuntimeLibraryFiles.kt @@ -20,13 +20,17 @@ import java.io.File class RuntimeLibraryFiles( val runtimeJar: File, + val reflectJar: File?, val runtimeSourcesJar: File ) { - fun getAllJars(): List = listOf(runtimeJar, runtimeSourcesJar) + fun getAllJars(): List = listOf(runtimeJar, reflectJar, runtimeSourcesJar).filterNotNull() fun getRuntimeDestination(dirToCopyJar: String): File = File(dirToCopyJar + "/" + runtimeJar.name) + fun getReflectDestination(dirToCopyJar: String): File? = + if (reflectJar != null) File(dirToCopyJar + "/" + reflectJar.name) else null + fun getRuntimeSourcesDestination(dirToCopyJar: String): File = File(dirToCopyJar + "/" + runtimeSourcesJar.name) } diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/CustomLibraryDescriptorWithDeferredConfig.java b/idea/src/org/jetbrains/kotlin/idea/framework/CustomLibraryDescriptorWithDeferredConfig.java index 87d74575c8e..7cf25c6299e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/framework/CustomLibraryDescriptorWithDeferredConfig.java +++ b/idea/src/org/jetbrains/kotlin/idea/framework/CustomLibraryDescriptorWithDeferredConfig.java @@ -173,20 +173,25 @@ public abstract class CustomLibraryDescriptorWithDeferredConfig extends CustomLi RuntimeLibraryFiles files = configurator.getExistingJarFiles(); - File libraryFile; - File librarySrcFile; + File runtimeJar; + File reflectJar; + File runtimeSrcJar; File stdJarInDefaultPath = files.getRuntimeDestination(defaultPathToJarFile); if (!useRelativePaths && stdJarInDefaultPath.exists()) { - libraryFile = stdJarInDefaultPath; + runtimeJar = stdJarInDefaultPath; - File sourcesJar = files.getRuntimeSourcesDestination(defaultPathToJarFile); - if (sourcesJar.exists()) { - librarySrcFile = sourcesJar; + reflectJar = files.getReflectDestination(defaultPathToJarFile); + if (reflectJar != null && !reflectJar.exists()) { + reflectJar = files.getReflectJar(); + assert reflectJar != null : "getReflectDestination != null, but getReflectJar == null"; + deferredCopyFileRequests.addCopyWithReplaceRequest(reflectJar, runtimeJar.getParent()); } - else { - librarySrcFile = files.getRuntimeSourcesJar(); - deferredCopyFileRequests.addCopyWithReplaceRequest(librarySrcFile, libraryFile.getParent()); + + runtimeSrcJar = files.getRuntimeSourcesDestination(defaultPathToJarFile); + if (!runtimeSrcJar.exists()) { + runtimeSrcJar = files.getRuntimeSourcesJar(); + deferredCopyFileRequests.addCopyWithReplaceRequest(runtimeSrcJar, runtimeJar.getParent()); } } else { @@ -202,23 +207,23 @@ public abstract class CustomLibraryDescriptorWithDeferredConfig extends CustomLi } } - libraryFile = files.getRuntimeJar(); - librarySrcFile = files.getRuntimeSourcesJar(); + runtimeJar = files.getRuntimeJar(); + reflectJar = files.getReflectJar(); + runtimeSrcJar = files.getRuntimeSourcesJar(); } - return createConfiguration(libraryFile, librarySrcFile); + return createConfiguration(Arrays.asList(runtimeJar, reflectJar), runtimeSrcJar); } @NotNull - protected NewLibraryConfiguration createConfiguration(@NotNull File libraryFile, @NotNull File librarySrcFile) { - final String libraryFileUrl = VfsUtil.getUrlForLibraryRoot(libraryFile); - final String libraryFileSrcUrl = VfsUtil.getUrlForLibraryRoot(librarySrcFile); - + protected NewLibraryConfiguration createConfiguration(@NotNull final List libraryFiles, @NotNull final File librarySrcFile) { return new NewLibraryConfiguration(libraryName, null, new LibraryVersionProperties()) { @Override public void addRoots(@NotNull LibraryEditor editor) { - editor.addRoot(libraryFileUrl, OrderRootType.CLASSES); - editor.addRoot(libraryFileSrcUrl, OrderRootType.SOURCES); + for (File libraryFile : libraryFiles) { + editor.addRoot(VfsUtil.getUrlForLibraryRoot(libraryFile), OrderRootType.CLASSES); + } + editor.addRoot(VfsUtil.getUrlForLibraryRoot(librarySrcFile), OrderRootType.SOURCES); } }; } diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdDescription.java b/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdDescription.java index 4f6b6045635..4a583c9cdb9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdDescription.java +++ b/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdDescription.java @@ -25,6 +25,7 @@ import org.jetbrains.annotations.TestOnly; import org.jetbrains.kotlin.idea.configuration.KotlinJsModuleConfigurator; import org.jetbrains.kotlin.idea.configuration.RuntimeLibraryFiles; +import java.util.Collections; import java.util.Set; import static org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtils.getConfiguratorByName; @@ -52,6 +53,6 @@ public class JSLibraryStdDescription extends CustomLibraryDescriptorWithDeferred assert configurator != null : "Cannot find configurator with name " + NAME; RuntimeLibraryFiles files = configurator.getExistingJarFiles(); - return createConfiguration(files.getRuntimeJar(), files.getRuntimeSourcesJar()); + return createConfiguration(Collections.singletonList(files.getRuntimeJar()), files.getRuntimeSourcesJar()); } } diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/JavaRuntimePresentationProvider.java b/idea/src/org/jetbrains/kotlin/idea/framework/JavaRuntimePresentationProvider.java index 7a014f46d1d..ae013ee54b7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/framework/JavaRuntimePresentationProvider.java +++ b/idea/src/org/jetbrains/kotlin/idea/framework/JavaRuntimePresentationProvider.java @@ -63,6 +63,11 @@ public class JavaRuntimePresentationProvider extends LibraryPresentationProvider return JavaRuntimeDetectionUtil.getRuntimeJar(Arrays.asList(library.getFiles(OrderRootType.CLASSES))); } + @Nullable + public static VirtualFile getReflectJar(@NotNull Library library) { + return LibraryUtils.getJarFile(Arrays.asList(library.getFiles(OrderRootType.CLASSES)), PathUtil.KOTLIN_JAVA_REFLECT_JAR); + } + @Nullable public static VirtualFile getRuntimeSrcJar(@NotNull Library library) { return getRuntimeSrcJar(Arrays.asList(library.getFiles(OrderRootType.SOURCES))); diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.java b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.java index 48d14d0d70c..128fdfc006e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.java +++ b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.java @@ -157,6 +157,7 @@ public class KotlinRuntimeLibraryUtil { for (Library library : libraries) { if (LibraryPresentationProviderUtil.isDetected(JavaRuntimePresentationProvider.getInstance(), library)) { updateJar(project, JavaRuntimePresentationProvider.getRuntimeJar(library), LibraryJarDescriptor.RUNTIME_JAR); + updateJar(project, JavaRuntimePresentationProvider.getReflectJar(library), LibraryJarDescriptor.REFLECT_JAR); if (configurator.changeOldSourcesPathIfNeeded(library)) { configurator.copySourcesToPathFromLibrary(library); @@ -184,15 +185,17 @@ public class KotlinRuntimeLibraryUtil { } KotlinPaths paths = PathUtil.getKotlinPathsForIdeaPlugin(); - File runtimePath = null; + File jarPath; switch (libraryJarDescriptor) { - case RUNTIME_JAR: runtimePath = paths.getRuntimePath(); break; - case RUNTIME_SRC_JAR: runtimePath = paths.getRuntimeSourcesPath(); break; - case JS_STDLIB_JAR: runtimePath = paths.getJsStdLibJarPath(); break; - case JS_STDLIB_SRC_JAR: runtimePath = paths.getJsStdLibSrcJarPath(); break; + case RUNTIME_JAR: jarPath = paths.getRuntimePath(); break; + case REFLECT_JAR: jarPath = paths.getReflectPath(); break; + case RUNTIME_SRC_JAR: jarPath = paths.getRuntimeSourcesPath(); break; + case JS_STDLIB_JAR: jarPath = paths.getJsStdLibJarPath(); break; + case JS_STDLIB_SRC_JAR: jarPath = paths.getJsStdLibSrcJarPath(); break; + default: jarPath = null; break; } - if (!runtimePath.exists()) { + if (!jarPath.exists()) { showRuntimeJarNotFoundDialog(project, libraryJarDescriptor.jarName).run(); return; } @@ -200,7 +203,7 @@ public class KotlinRuntimeLibraryUtil { VirtualFile localJar = getLocalJar(fileToReplace); assert localJar != null; - replaceFile(runtimePath, localJar); + replaceFile(jarPath, localJar); } @NotNull @@ -231,6 +234,7 @@ public class KotlinRuntimeLibraryUtil { private enum LibraryJarDescriptor { RUNTIME_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_JAR, true), + REFLECT_JAR(PathUtil.KOTLIN_JAVA_REFLECT_JAR, false), RUNTIME_SRC_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_SRC_JAR, false), JS_STDLIB_JAR(PathUtil.JS_LIB_JAR_NAME, true), JS_STDLIB_SRC_JAR(PathUtil.JS_LIB_SRC_JAR_NAME, false); diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinUpdatePluginComponent.kt b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinUpdatePluginComponent.kt index 2a812fe45c5..323d987478b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinUpdatePluginComponent.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinUpdatePluginComponent.kt @@ -16,19 +16,19 @@ package org.jetbrains.kotlin.idea.versions -import com.intellij.openapi.components.ApplicationComponent -import org.jetbrains.kotlin.utils.PathUtil -import com.intellij.openapi.vfs.JarFileSystem import com.intellij.ide.util.PropertiesComponent -import org.jetbrains.kotlin.idea.JetPluginUtil -import com.intellij.util.indexing.FileBasedIndex +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.ApplicationComponent +import com.intellij.openapi.vfs.JarFileSystem import com.intellij.openapi.vfs.LocalFileSystem -import java.io.File +import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFileVisitor import com.intellij.openapi.vfs.newvfs.NewVirtualFile -import com.intellij.openapi.vfs.VfsUtilCore +import com.intellij.util.indexing.FileBasedIndex +import org.jetbrains.kotlin.idea.JetPluginUtil import org.jetbrains.kotlin.idea.vfilefinder.KotlinClassFileIndex -import com.intellij.openapi.application.ApplicationManager +import org.jetbrains.kotlin.utils.PathUtil +import java.io.File private val INSTALLED_KOTLIN_VERSION = "installed.kotlin.plugin.version" @@ -49,6 +49,7 @@ class KotlinUpdatePluginComponent : ApplicationComponent { // Force refresh jar handlers requestFullJarUpdate(ideaPluginPaths.getRuntimePath()) + requestFullJarUpdate(ideaPluginPaths.getReflectPath()) requestFullJarUpdate(ideaPluginPaths.getRuntimeSourcesPath()) requestFullJarUpdate(ideaPluginPaths.getJsStdLibJarPath())