New Kotlin projects and Configure Kotlin adds JRE-specific jars

This commit is contained in:
Dmitry Jemerov
2017-04-10 17:29:04 +02:00
parent aacaa61cf2
commit aee32e6204
7 changed files with 86 additions and 43 deletions
@@ -35,6 +35,10 @@ public class PathUtil {
public static final String NOARG_PLUGIN_JAR_NAME = "noarg-compiler-plugin.jar";
public static final String JS_LIB_SRC_JAR_NAME = "kotlin-stdlib-js-sources.jar";
public static final String KOTLIN_JAVA_RUNTIME_JAR = "kotlin-runtime.jar";
public static final String KOTLIN_JAVA_RUNTIME_JRE7_JAR = "kotlin-stdlib-jre7.jar";
public static final String KOTLIN_JAVA_RUNTIME_JRE8_JAR = "kotlin-stdlib-jre8.jar";
public static final String KOTLIN_JAVA_RUNTIME_JRE7_SRC_JAR = "kotlin-stdlib-jre7-sources.jar";
public static final String KOTLIN_JAVA_RUNTIME_JRE8_SRC_JAR = "kotlin-stdlib-jre8-sources.jar";
public static final String KOTLIN_JAVA_STDLIB_JAR = "kotlin-stdlib.jar";
public static final String KOTLIN_JAVA_REFLECT_JAR = "kotlin-reflect.jar";
public static final String KOTLIN_JAVA_SCRIPT_RUNTIME_JAR = "kotlin-script-runtime.jar";
@@ -18,13 +18,15 @@ package org.jetbrains.kotlin.idea.configuration
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.module.Module
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.libraries.Library
import org.jetbrains.kotlin.idea.framework.JavaRuntimeLibraryDescription
import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor
import org.jetbrains.kotlin.idea.versions.isKotlinJavaRuntime
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.utils.PathUtil
open class KotlinJavaModuleConfigurator internal constructor() : KotlinWithLibraryConfigurator() {
@@ -53,11 +55,21 @@ open class KotlinJavaModuleConfigurator internal constructor() : KotlinWithLibra
override val targetPlatform: TargetPlatform
get() = JvmPlatform
override val libraryJarDescriptors: List<LibraryJarDescriptor>
get() = listOf(LibraryJarDescriptor.RUNTIME_JAR,
LibraryJarDescriptor.REFLECT_JAR,
LibraryJarDescriptor.RUNTIME_SRC_JAR,
LibraryJarDescriptor.TEST_JAR)
override fun getLibraryJarDescriptors(sdk: Sdk?): List<LibraryJarDescriptor> {
var result = listOf(LibraryJarDescriptor.RUNTIME_JAR,
LibraryJarDescriptor.REFLECT_JAR,
LibraryJarDescriptor.RUNTIME_SRC_JAR,
LibraryJarDescriptor.TEST_JAR)
val sdkVersion = sdk?.let { JavaSdk.getInstance().getVersion(it) } ?: return result
if (sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7)) {
result += listOf(LibraryJarDescriptor.RUNTIME_JRE7_JAR, LibraryJarDescriptor.RUNTIME_JRE7_SOURCES_JAR)
}
if (sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_8)) {
result += listOf(LibraryJarDescriptor.RUNTIME_JRE8_JAR, LibraryJarDescriptor.RUNTIME_JRE8_SOURCES_JAR)
}
return result
}
override val libraryMatcher: (Library) -> Boolean
get() = ::isKotlinJavaRuntime
@@ -17,17 +17,17 @@
package org.jetbrains.kotlin.idea.configuration;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.libraries.Library;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription;
import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor;
import org.jetbrains.kotlin.idea.versions.OutdatedKotlinRuntimeCheckerKt;
import org.jetbrains.kotlin.js.JavaScript;
import org.jetbrains.kotlin.js.resolve.JsPlatform;
import org.jetbrains.kotlin.resolve.TargetPlatform;
import org.jetbrains.kotlin.utils.KotlinPaths;
import org.jetbrains.kotlin.utils.PathUtil;
import java.util.Arrays;
import java.util.List;
@@ -84,7 +84,7 @@ public class KotlinJsModuleConfigurator extends KotlinWithLibraryConfigurator {
@NotNull
@Override
public List<LibraryJarDescriptor> getLibraryJarDescriptors() {
public List<LibraryJarDescriptor> getLibraryJarDescriptors(@Nullable Sdk sdk) {
return Arrays.asList(LibraryJarDescriptor.JS_STDLIB_JAR,
LibraryJarDescriptor.JS_STDLIB_SRC_JAR);
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.*
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
@@ -112,19 +113,24 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
?: getKotlinLibrary(project)
?: createNewLibrary(project, collector)
for (descriptor in libraryJarDescriptors) {
val sdk = ModuleRootManager.getInstance(module).sdk
val model = library.modifiableModel
for (descriptor in getLibraryJarDescriptors(sdk)) {
val dirToCopyJar = getPathToCopyFileTo(project, descriptor.orderRootType, defaultPath, pathFromDialog)
val runtimeState = getJarState(project,
File(dirToCopyJar, descriptor.jarName),
descriptor.orderRootType, pathFromDialog == null)
configureLibraryJar(module, library, runtimeState, dirToCopyJar, descriptor, collector)
configureLibraryJar(model, runtimeState, dirToCopyJar, descriptor, collector)
}
ApplicationManager.getApplication().runWriteAction { model.commit() }
addLibraryToModuleIfNeeded(module, library, collector)
}
fun configureLibraryJar(
module: Module,
library: Library,
library: Library.ModifiableModel,
jarState: FileState,
dirToCopyJarTo: String,
libraryJarDescriptor: LibraryJarDescriptor,
@@ -151,14 +157,10 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
}
if (jarRoot !in library.getFiles(libraryJarDescriptor.orderRootType)) {
val model = library.modifiableModel
model.addRoot(jarRoot, libraryJarDescriptor.orderRootType)
library.addRoot(jarRoot, libraryJarDescriptor.orderRootType)
ApplicationManager.getApplication().runWriteAction { model.commit() }
collector.addMessage("Added $jarFile to library configuration")
}
addLibraryToModuleIfNeeded(module, library, collector)
}
fun getKotlinLibrary(project: Project): Library? {
@@ -181,7 +183,7 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
return getPathFromLibrary(getKotlinLibrary(project), type)
}
private fun addLibraryToModuleIfNeeded(module: Module, library: Library, collector: NotificationMessageCollector) {
fun addLibraryToModuleIfNeeded(module: Module, library: Library, collector: NotificationMessageCollector) {
val expectedDependencyScope = getDependencyScope(module)
val kotlinLibrary = getKotlinLibrary(module)
if (kotlinLibrary == null) {
@@ -231,7 +233,8 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
protected fun needToChooseJarPath(project: Project): Boolean {
val defaultPath = getDefaultPathToJarFile(project)
return !isProjectLibraryPresent(project) && !File(defaultPath, libraryJarDescriptors.first().jarName).exists()
return !isProjectLibraryPresent(project) &&
!File(defaultPath, getLibraryJarDescriptors(null).first().jarName).exists()
}
protected open fun getDefaultPathToJarFile(project: Project): String {
@@ -280,7 +283,7 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
return defaultDir
}
abstract val libraryJarDescriptors: List<LibraryJarDescriptor>
abstract fun getLibraryJarDescriptors(sdk: Sdk?): List<LibraryJarDescriptor>
companion object {
val DEFAULT_LIBRARY_DIR = "lib"
@@ -291,7 +294,7 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
!KotlinPluginUtil.isGradleModule(module)
}
protected fun getPathFromLibrary(library: Library?, type: OrderRootType): String? {
fun getPathFromLibrary(library: Library?, type: OrderRootType): String? {
if (library == null) return null
val libraryFiles = library.getUrls(type)
@@ -32,6 +32,9 @@ import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigurator
import org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigurator.FileState.COPY
import org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY
import org.jetbrains.kotlin.idea.configuration.NotificationMessageCollector
import org.jetbrains.kotlin.idea.configuration.createConfigureKotlinNotificationCollector
import org.jetbrains.kotlin.idea.configuration.getConfiguratorByName
import org.jetbrains.kotlin.idea.framework.ui.CreateLibraryDialog
@@ -40,7 +43,6 @@ import org.jetbrains.kotlin.idea.util.projectStructure.findLibrary
import org.jetbrains.kotlin.idea.util.projectStructure.getModuleDir
import org.jetbrains.kotlin.idea.util.projectStructure.replaceFileRoot
import java.io.File
import java.util.*
import javax.swing.JComponent
/**
@@ -48,7 +50,7 @@ import javax.swing.JComponent
*/
abstract class CustomLibraryDescriptorWithDeferredConfig
(
project: Project?,
val project: Project?,
private val configuratorName: String,
private val libraryName: String,
private val dialogTitle: String,
@@ -66,18 +68,32 @@ abstract class CustomLibraryDescriptorWithDeferredConfig
}
fun finishLibConfiguration(module: Module, rootModel: ModifiableRootModel) {
val deferredCopyFileRequests = copyFileRequests ?: return
val library = rootModel.orderEntries().findLibrary { library ->
val libraryPresentationManager = LibraryPresentationManager.getInstance()
val classFiles = Arrays.asList(*library.getFiles(OrderRootType.CLASSES))
val classFiles = library.getFiles(OrderRootType.CLASSES).toList()
libraryPresentationManager.isLibraryOfKind(classFiles, libraryKind)
} ?: return
val model = library.modifiableModel
val copyToPath = KotlinWithLibraryConfigurator.getPathFromLibrary(library, OrderRootType.CLASSES)
try {
deferredCopyFileRequests.performRequests(module.project, module.getModuleDir(), model)
val collector = createConfigureKotlinNotificationCollector(module.project)
copyFileRequests?.performRequests(module.getModuleDir(), model, collector)
if (copyToPath != null) {
val jarState = if (copyFileRequests == null) DO_NOT_COPY else COPY
// Now that we know the SDK which is going to be set for the module, we can add jre 7/8 if required
val descriptorsWithSdk = configurator.getLibraryJarDescriptors(rootModel.sdk)
for (jarDescriptor in descriptorsWithSdk) {
if (model.getFiles(jarDescriptor.orderRootType).any { it.name == jarDescriptor.jarName })
continue
configurator.configureLibraryJar(model, jarState, copyToPath, jarDescriptor, collector)
}
}
collector.showNotification()
}
finally {
model.commit()
@@ -87,8 +103,7 @@ abstract class CustomLibraryDescriptorWithDeferredConfig
class DeferredCopyFileRequests(private val configurator: KotlinWithLibraryConfigurator) {
private val copyFilesRequests = Lists.newArrayList<CopyFileRequest>()
fun performRequests(project: Project, relativePath: String, model: Library.ModifiableModel) {
val collector = createConfigureKotlinNotificationCollector(project)
fun performRequests(relativePath: String, model: Library.ModifiableModel, collector: NotificationMessageCollector) {
for (request in copyFilesRequests) {
val destinationPath = if (FileUtil.isAbsolute(request.toDir))
request.toDir
@@ -101,7 +116,6 @@ abstract class CustomLibraryDescriptorWithDeferredConfig
model.replaceFileRoot(request.file, resultFile)
}
}
collector.showNotification()
}
fun addCopyWithReplaceRequest(file: File, copyIntoPath: String) {
@@ -121,7 +135,7 @@ abstract class CustomLibraryDescriptorWithDeferredConfig
else
FileUIUtils.createRelativePath(null, projectBaseDir, DEFAULT_LIB_DIR_NAME)
val jarDescriptors = configurator.libraryJarDescriptors
val jarDescriptors = configurator.getLibraryJarDescriptors(null)
val stdJarInDefaultPath = File(defaultPathToJarFile, jarDescriptors.first().jarName)
val libraryFiles = mutableListOf<File>()
@@ -150,7 +164,7 @@ abstract class CustomLibraryDescriptorWithDeferredConfig
val copyIntoPath = dialog.copyIntoPath
if (copyIntoPath != null) {
for (libraryJarDescriptor in configurator.libraryJarDescriptors) {
for (libraryJarDescriptor in configurator.getLibraryJarDescriptors(null)) {
copyFileRequests!!.addCopyWithReplaceRequest(libraryJarDescriptor.getPathInPlugin(), copyIntoPath)
}
}
@@ -184,7 +198,7 @@ abstract class CustomLibraryDescriptorWithDeferredConfig
collectPathsInPlugin(OrderRootType.SOURCES))
private fun collectPathsInPlugin(rootType: OrderRootType): List<File> {
return configurator.libraryJarDescriptors
return configurator.getLibraryJarDescriptors(null)
.filter { it.orderRootType == rootType }
.map { it.getPathInPlugin() }
}
@@ -24,10 +24,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.roots.*
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.io.FileUtil
@@ -96,12 +93,14 @@ fun updateLibraries(project: Project, libraries: Collection<Library>) {
error("Configurator with given name doesn't exists: " + KotlinJsModuleConfigurator.NAME)
val collector = createConfigureKotlinNotificationCollector(project)
val sdk = ProjectRootManager.getInstance(project).projectSdk
// TODO use module SDK
for (library in libraries) {
val libraryJarDescriptors = if (isDetected(JavaRuntimePresentationProvider.getInstance(), library))
kJvmConfigurator.libraryJarDescriptors
kJvmConfigurator.getLibraryJarDescriptors(sdk)
else
kJsConfigurator.libraryJarDescriptors
kJsConfigurator.getLibraryJarDescriptors(sdk)
for (libraryJarDescriptor in libraryJarDescriptors) {
updateJar(project, library, libraryJarDescriptor)
@@ -167,7 +166,7 @@ fun findAllUsedLibraries(project: Project): MultiMap<Library, Module> {
enum class LibraryJarDescriptor(val jarName: String,
val orderRootType: OrderRootType,
val shouldExist: Boolean,
val getPath: (KotlinPaths) -> File) {
val getPath: (KotlinPaths) -> File = { paths -> File(paths.libPath, jarName) }) {
RUNTIME_JAR(PathUtil.KOTLIN_JAVA_STDLIB_JAR, OrderRootType.CLASSES, true, KotlinPaths::getStdlibPath) {
override fun findExistingJar(library: Library): VirtualFile? {
if (isExternalLibrary(library)) return null
@@ -178,6 +177,10 @@ enum class LibraryJarDescriptor(val jarName: String,
REFLECT_JAR(PathUtil.KOTLIN_JAVA_REFLECT_JAR, OrderRootType.CLASSES, false, KotlinPaths::getReflectPath),
SCRIPT_RUNTIME_JAR(PathUtil.KOTLIN_JAVA_SCRIPT_RUNTIME_JAR, OrderRootType.CLASSES, true, KotlinPaths::getScriptRuntimePath),
TEST_JAR(PathUtil.KOTLIN_TEST_JAR, OrderRootType.CLASSES, false, KotlinPaths::getKotlinTestPath),
RUNTIME_JRE7_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_JRE7_JAR, OrderRootType.CLASSES, false),
RUNTIME_JRE8_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_JRE8_JAR, OrderRootType.CLASSES, false),
RUNTIME_JRE7_SOURCES_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_JRE7_SRC_JAR, OrderRootType.SOURCES, false),
RUNTIME_JRE8_SOURCES_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_JRE8_SRC_JAR, OrderRootType.SOURCES, false),
RUNTIME_SRC_JAR(PathUtil.KOTLIN_JAVA_STDLIB_SRC_JAR, OrderRootType.SOURCES, false, KotlinPaths::getStdlibSourcesPath) {
override fun findExistingJar(library: Library): VirtualFile? {
@@ -16,10 +16,13 @@
package org.jetbrains.kotlin.idea.configuration;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathMacros;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
@@ -67,9 +70,13 @@ public abstract class AbstractConfigureKotlinTest extends PlatformTestCase {
library = configurator.createNewLibrary(project, collector);
}
String pathToJar = getPathToJar(runtimeState, jarFromDist, jarFromTemp);
for (LibraryJarDescriptor descriptor : configurator.getLibraryJarDescriptors()) {
configurator.configureLibraryJar(module, library, runtimeState, pathToJar, descriptor, collector);
Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
Library.ModifiableModel model = library.getModifiableModel();
for (LibraryJarDescriptor descriptor : configurator.getLibraryJarDescriptors(sdk)) {
configurator.configureLibraryJar(model, runtimeState, pathToJar, descriptor, collector);
}
ApplicationManager.getApplication().runWriteAction(model::commit);
configurator.addLibraryToModuleIfNeeded(module, library, collector);
}
collector.showNotification();
}