Rewrite configureModuleWithLibrary() based on LibraryJarDescriptor
Also remove duplicated logic for identifying Kotlin libraries.
This commit is contained in:
+1
-1
@@ -53,7 +53,7 @@ object JsLibraryStdDetectionUtil {
|
||||
return JarUtil.getJarAttribute(VfsUtilCore.virtualToIoFile(jar), Attributes.Name.IMPLEMENTATION_VERSION)
|
||||
}
|
||||
|
||||
private fun getJsStdLibJar(classesRoots: List<VirtualFile>): VirtualFile? {
|
||||
fun getJsStdLibJar(classesRoots: List<VirtualFile>): VirtualFile? {
|
||||
for (root in classesRoots) {
|
||||
if (root.fileSystem.protocol !== StandardFileSystems.JAR_PROTOCOL) continue
|
||||
|
||||
|
||||
@@ -18,12 +18,10 @@ package org.jetbrains.kotlin.idea.configuration
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.impl.scopes.LibraryScope
|
||||
import com.intellij.openapi.project.Project
|
||||
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.getKotlinJvmRuntimeMarkerClass
|
||||
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
|
||||
@@ -71,14 +69,8 @@ open class KotlinJavaModuleConfigurator internal constructor() : KotlinWithLibra
|
||||
LibraryJarDescriptor.RUNTIME_SRC_JAR,
|
||||
LibraryJarDescriptor.TEST_JAR)
|
||||
|
||||
override fun isKotlinLibrary(project: Project, library: Library): Boolean {
|
||||
if (super.isKotlinLibrary(project, library)) {
|
||||
return true
|
||||
}
|
||||
|
||||
val scope = LibraryScope(project, library)
|
||||
return getKotlinJvmRuntimeMarkerClass(project, scope) != null
|
||||
}
|
||||
override val libraryMatcher: (Library) -> Boolean
|
||||
get() = ::isKotlinJavaRuntime
|
||||
|
||||
companion object {
|
||||
val NAME = "java"
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
package org.jetbrains.kotlin.idea.configuration;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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;
|
||||
@@ -97,6 +100,12 @@ public class KotlinJsModuleConfigurator extends KotlinWithLibraryConfigurator {
|
||||
LibraryJarDescriptor.JS_STDLIB_SRC_JAR);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Function1<Library, Boolean> getLibraryMatcher() {
|
||||
return OutdatedKotlinRuntimeCheckerKt::isKotlinJsRuntime;
|
||||
}
|
||||
|
||||
KotlinJsModuleConfigurator() {
|
||||
}
|
||||
}
|
||||
|
||||
+57
-211
@@ -23,18 +23,18 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.*
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.annotations.Contract
|
||||
import org.jetbrains.kotlin.idea.KotlinPluginUtil
|
||||
import org.jetbrains.kotlin.idea.framework.ui.CreateLibraryDialogWithModules
|
||||
import org.jetbrains.kotlin.idea.framework.ui.FileUIUtils
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor
|
||||
import org.jetbrains.kotlin.idea.versions.findKotlinRuntimeLibrary
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
@@ -114,122 +114,60 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
|
||||
) {
|
||||
val project = module.project
|
||||
|
||||
val files = existingJarFiles
|
||||
val libraryState = getLibraryState(project)
|
||||
val dirToCopyJar = getPathToCopyFileTo(project, OrderRootType.CLASSES, defaultPath, pathFromDialog)
|
||||
val runtimeState = getJarState(project, files.getRuntimeDestination(dirToCopyJar), OrderRootType.CLASSES, pathFromDialog == null)
|
||||
val library = getKotlinLibrary(module) ?: createNewLibrary(project, collector)
|
||||
|
||||
configureModuleWithLibraryClasses(module, libraryState, runtimeState, dirToCopyJar, collector)
|
||||
for (descriptor in libraryJarDescriptors) {
|
||||
val dirToCopyJar = getPathToCopyFileTo(project, descriptor.orderRootType, defaultPath, pathFromDialog)
|
||||
val runtimeState = getJarState(project,
|
||||
File(dirToCopyJar, descriptor.jarName),
|
||||
descriptor.orderRootType, pathFromDialog == null)
|
||||
|
||||
val library = getKotlinLibrary(project) ?: return
|
||||
|
||||
val dirToCopySourcesJar = getPathToCopyFileTo(project, OrderRootType.SOURCES, defaultPath, pathFromDialog)
|
||||
val sourcesState = getJarState(project, files.getRuntimeSourcesDestination(dirToCopySourcesJar), OrderRootType.SOURCES,
|
||||
pathFromDialog == null)
|
||||
|
||||
configureModuleWithLibrarySources(library, sourcesState, dirToCopySourcesJar, collector)
|
||||
}
|
||||
|
||||
fun configureModuleWithLibraryClasses(
|
||||
module: Module,
|
||||
libraryState: LibraryState,
|
||||
jarState: FileState,
|
||||
dirToCopyJarTo: String,
|
||||
collector: NotificationMessageCollector
|
||||
) {
|
||||
val project = module.project
|
||||
val files = existingJarFiles
|
||||
val runtimeJar = files.runtimeJar
|
||||
val reflectJar = files.reflectJar
|
||||
|
||||
when (libraryState) {
|
||||
KotlinWithLibraryConfigurator.LibraryState.LIBRARY -> when (jarState) {
|
||||
KotlinWithLibraryConfigurator.FileState.EXISTS -> {
|
||||
}
|
||||
KotlinWithLibraryConfigurator.FileState.COPY -> {
|
||||
copyFileToDir(runtimeJar, dirToCopyJarTo, collector)
|
||||
if (reflectJar != null) {
|
||||
copyFileToDir(reflectJar, dirToCopyJarTo, collector)
|
||||
}
|
||||
}
|
||||
KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY -> {
|
||||
throw IllegalStateException(
|
||||
"Kotlin library exists, so path to copy should be hidden in configuration dialog and jar should be copied using path in library table")
|
||||
}
|
||||
}
|
||||
KotlinWithLibraryConfigurator.LibraryState.NON_CONFIGURED_LIBRARY -> when (jarState) {
|
||||
KotlinWithLibraryConfigurator.FileState.EXISTS -> {
|
||||
addJarsToExistingLibrary(
|
||||
project, files.getRuntimeDestination(dirToCopyJarTo), files.getReflectDestination(dirToCopyJarTo), collector
|
||||
)
|
||||
}
|
||||
KotlinWithLibraryConfigurator.FileState.COPY -> {
|
||||
val copiedRuntimeJar = copyFileToDir(runtimeJar, dirToCopyJarTo, collector)
|
||||
val copiedReflectJar = copyFileToDir(reflectJar, dirToCopyJarTo, collector)
|
||||
addJarsToExistingLibrary(project, copiedRuntimeJar!!, copiedReflectJar, collector)
|
||||
}
|
||||
KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY -> {
|
||||
addJarsToExistingLibrary(project, runtimeJar, reflectJar, collector)
|
||||
}
|
||||
}
|
||||
KotlinWithLibraryConfigurator.LibraryState.NEW_LIBRARY -> when (jarState) {
|
||||
KotlinWithLibraryConfigurator.FileState.EXISTS -> {
|
||||
addJarsToNewLibrary(
|
||||
project, files.getRuntimeDestination(dirToCopyJarTo), files.getReflectDestination(dirToCopyJarTo), collector
|
||||
)
|
||||
}
|
||||
KotlinWithLibraryConfigurator.FileState.COPY -> {
|
||||
val copiedRuntimeJar = copyFileToDir(runtimeJar, dirToCopyJarTo, collector)
|
||||
val copiedReflectJar = copyFileToDir(reflectJar, dirToCopyJarTo, collector)
|
||||
addJarsToNewLibrary(project, copiedRuntimeJar!!, copiedReflectJar, collector)
|
||||
}
|
||||
KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY -> {
|
||||
addJarsToNewLibrary(project, runtimeJar, reflectJar, collector)
|
||||
}
|
||||
}
|
||||
configureLibraryJar(module, library, runtimeState, dirToCopyJar, descriptor, collector)
|
||||
}
|
||||
|
||||
addLibraryToModuleIfNeeded(module, collector)
|
||||
}
|
||||
|
||||
protected fun configureModuleWithLibrarySources(
|
||||
fun configureLibraryJar(
|
||||
module: Module,
|
||||
library: Library,
|
||||
jarState: FileState,
|
||||
dirToCopyJarTo: String?,
|
||||
dirToCopyJarTo: String,
|
||||
libraryJarDescriptor: LibraryJarDescriptor,
|
||||
collector: NotificationMessageCollector
|
||||
) {
|
||||
val files = existingJarFiles
|
||||
val runtimeSourcesJar = files.runtimeSourcesJar
|
||||
when (jarState) {
|
||||
KotlinWithLibraryConfigurator.FileState.EXISTS -> {
|
||||
if (dirToCopyJarTo != null) {
|
||||
addSourcesToLibraryIfNeeded(library, files.getRuntimeSourcesDestination(dirToCopyJarTo), collector)
|
||||
}
|
||||
}
|
||||
KotlinWithLibraryConfigurator.FileState.COPY -> {
|
||||
assert(dirToCopyJarTo != null) { "Path to copy should be non-null" }
|
||||
val file = copyFileToDir(runtimeSourcesJar, dirToCopyJarTo!!, collector)
|
||||
addSourcesToLibraryIfNeeded(library, file!!, collector)
|
||||
}
|
||||
KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY -> {
|
||||
addSourcesToLibraryIfNeeded(library, runtimeSourcesJar, collector)
|
||||
}
|
||||
val jarFile = if (jarState == KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY)
|
||||
libraryJarDescriptor.getPathInPlugin()
|
||||
else
|
||||
File(dirToCopyJarTo, libraryJarDescriptor.jarName)
|
||||
|
||||
if (jarState == KotlinWithLibraryConfigurator.FileState.COPY) {
|
||||
copyFileToDir(libraryJarDescriptor.getPathInPlugin(), dirToCopyJarTo, collector)
|
||||
}
|
||||
|
||||
val jarVFile = LocalFileSystem.getInstance().findFileByIoFile(jarFile)
|
||||
if (jarVFile == null) {
|
||||
collector.addMessage("Can't find library JAR file " + jarFile)
|
||||
return
|
||||
}
|
||||
val jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(jarVFile)
|
||||
if (jarRoot == null) {
|
||||
collector.addMessage("Couldn't configure library; JAR file $jarVFile may be corrupted")
|
||||
return
|
||||
}
|
||||
|
||||
if (jarRoot !in library.getFiles(libraryJarDescriptor.orderRootType)) {
|
||||
val model = library.modifiableModel
|
||||
model.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? {
|
||||
val librariesContainer = LibrariesContainerFactory.createContainer(project)
|
||||
for (library in librariesContainer.getLibraries(LibrariesContainer.LibraryLevel.PROJECT)) {
|
||||
if (isKotlinLibrary(project, library)) {
|
||||
return library
|
||||
}
|
||||
}
|
||||
for (library in librariesContainer.getLibraries(LibrariesContainer.LibraryLevel.GLOBAL)) {
|
||||
if (isKotlinLibrary(project, library)) {
|
||||
return library
|
||||
}
|
||||
}
|
||||
return null
|
||||
return LibraryTablesRegistrar.getInstance().getLibraryTable(project).libraries.firstOrNull(this::isKotlinLibrary) ?:
|
||||
LibraryTablesRegistrar.getInstance().libraryTable.libraries.firstOrNull(this::isKotlinLibrary)
|
||||
}
|
||||
|
||||
@Contract("!null, _, _ -> !null")
|
||||
@@ -247,12 +185,10 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
|
||||
return getPathFromLibrary(getKotlinLibrary(project), type)
|
||||
}
|
||||
|
||||
private fun addLibraryToModuleIfNeeded(module: Module, collector: NotificationMessageCollector) {
|
||||
private fun addLibraryToModuleIfNeeded(module: Module, library: Library, collector: NotificationMessageCollector) {
|
||||
val expectedDependencyScope = getDependencyScope(module)
|
||||
val kotlinLibrary = getKotlinLibrary(module)
|
||||
if (kotlinLibrary == null) {
|
||||
val library = getKotlinLibrary(module.project) ?: error("Kotlin project library should exists")
|
||||
|
||||
ModuleRootModificationUtil.addDependency(module, library, expectedDependencyScope, false)
|
||||
collector.addMessage(library.name + " library was added to module " + module.name)
|
||||
}
|
||||
@@ -271,44 +207,17 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
|
||||
}
|
||||
}
|
||||
|
||||
private fun addJarsToExistingLibrary(project: Project, runtimeJar: File, reflectJar: File?, collector: NotificationMessageCollector) {
|
||||
val library = getKotlinLibrary(project) ?: error("Kotlin library should present, instead createNewLibrary should be invoked")
|
||||
|
||||
val model = library.modifiableModel
|
||||
model.addRoot(VfsUtil.getUrlForLibraryRoot(runtimeJar), OrderRootType.CLASSES)
|
||||
if (reflectJar != null) {
|
||||
model.addRoot(VfsUtil.getUrlForLibraryRoot(reflectJar), OrderRootType.CLASSES)
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction { model.commit() }
|
||||
|
||||
collector.addMessage(library.name!! + " library was configured")
|
||||
}
|
||||
|
||||
private fun addJarsToNewLibrary(
|
||||
fun createNewLibrary(
|
||||
project: Project,
|
||||
runtimeJar: File,
|
||||
reflectJar: File?,
|
||||
collector: NotificationMessageCollector
|
||||
) {
|
||||
): Library {
|
||||
val table = LibraryTablesRegistrar.getInstance().getLibraryTable(project)
|
||||
val library = Ref<Library>()
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
library.set(table.createLibrary(libraryName))
|
||||
val model = library.get().modifiableModel
|
||||
model.addRoot(VfsUtil.getUrlForLibraryRoot(runtimeJar), OrderRootType.CLASSES)
|
||||
if (reflectJar != null) {
|
||||
model.addRoot(VfsUtil.getUrlForLibraryRoot(reflectJar), OrderRootType.CLASSES)
|
||||
}
|
||||
model.commit()
|
||||
val library = runWriteAction {
|
||||
table.createLibrary(libraryName)
|
||||
}
|
||||
|
||||
collector.addMessage(library.get().name!! + " library was created")
|
||||
}
|
||||
|
||||
private fun isProjectLibraryWithoutPathsPresent(project: Project): Boolean {
|
||||
val library = getKotlinLibrary(project)
|
||||
return library != null && library.getUrls(OrderRootType.CLASSES).size == 0
|
||||
collector.addMessage(library.name!! + " library was created")
|
||||
return library!!
|
||||
}
|
||||
|
||||
private fun isProjectLibraryPresent(project: Project): Boolean {
|
||||
@@ -316,33 +225,13 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
|
||||
return library != null && library.getUrls(OrderRootType.CLASSES).size > 0
|
||||
}
|
||||
|
||||
private fun getKotlinLibrary(module: Module): Library? {
|
||||
val result = Ref.create<Library>(null)
|
||||
OrderEnumerator.orderEntries(module).forEachLibrary(Processor<Library> { library ->
|
||||
if (isKotlinLibrary(module.project, library)) {
|
||||
result.set(library)
|
||||
return@Processor false
|
||||
}
|
||||
true
|
||||
})
|
||||
return result.get()
|
||||
protected abstract val libraryMatcher: (Library) -> Boolean
|
||||
|
||||
fun getKotlinLibrary(module: Module): Library? {
|
||||
return findKotlinRuntimeLibrary(module, this::isKotlinLibrary)
|
||||
}
|
||||
|
||||
protected open fun isKotlinLibrary(project: Project, library: Library): Boolean {
|
||||
if (libraryName == library.name) {
|
||||
return true
|
||||
}
|
||||
|
||||
val fileName = existingJarFiles.runtimeJar.name
|
||||
|
||||
for (root in library.getFiles(OrderRootType.CLASSES)) {
|
||||
if (root.name == fileName) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
private fun isKotlinLibrary(library: Library) = library.name == libraryName || libraryMatcher(library)
|
||||
|
||||
protected fun needToChooseJarPath(project: Project): Boolean {
|
||||
val defaultPath = getDefaultPathToJarFile(project)
|
||||
@@ -363,22 +252,6 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
|
||||
DO_NOT_COPY
|
||||
}
|
||||
|
||||
enum class LibraryState {
|
||||
LIBRARY,
|
||||
NON_CONFIGURED_LIBRARY,
|
||||
NEW_LIBRARY
|
||||
}
|
||||
|
||||
fun getLibraryState(project: Project): LibraryState {
|
||||
if (isProjectLibraryPresent(project)) {
|
||||
return LibraryState.LIBRARY
|
||||
}
|
||||
else if (isProjectLibraryWithoutPathsPresent(project)) {
|
||||
return LibraryState.NON_CONFIGURED_LIBRARY
|
||||
}
|
||||
return LibraryState.NEW_LIBRARY
|
||||
}
|
||||
|
||||
protected fun getJarState(
|
||||
project: Project,
|
||||
targetFile: File,
|
||||
@@ -415,13 +288,6 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
|
||||
return defaultDir
|
||||
}
|
||||
|
||||
protected fun assertFileExists(file: File): File {
|
||||
if (!file.exists()) {
|
||||
showError("Couldn't find file: " + file.path)
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
abstract val libraryJarDescriptors: List<LibraryJarDescriptor>
|
||||
|
||||
companion object {
|
||||
@@ -449,26 +315,6 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
|
||||
return parentDir
|
||||
}
|
||||
|
||||
protected fun addSourcesToLibraryIfNeeded(
|
||||
library: Library,
|
||||
file: File,
|
||||
collector: NotificationMessageCollector
|
||||
): Boolean {
|
||||
val librarySourceRoots = library.getUrls(OrderRootType.SOURCES)
|
||||
val librarySourceRoot = VfsUtil.getUrlForLibraryRoot(file)
|
||||
for (sourceRoot in librarySourceRoots) {
|
||||
if (sourceRoot == librarySourceRoot) return false
|
||||
}
|
||||
|
||||
val model = library.modifiableModel
|
||||
model.addRoot(librarySourceRoot, OrderRootType.SOURCES)
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction { model.commit() }
|
||||
|
||||
collector.addMessage("Source root '" + librarySourceRoot + "' was added to " + library.name + " library")
|
||||
return true
|
||||
}
|
||||
|
||||
private fun findLibraryOrderEntry(orderEntries: Array<OrderEntry>, library: Library): LibraryOrderEntry? {
|
||||
for (orderEntry in orderEntries) {
|
||||
if (orderEntry is LibraryOrderEntry && library == orderEntry.library) {
|
||||
|
||||
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.io.File
|
||||
|
||||
@@ -119,7 +118,7 @@ abstract class AddKotlinLibQuickFix(element: KtElement, val libraryJarDescriptor
|
||||
protected abstract fun getLibraryDescriptor(module: Module): MavenExternalLibraryDescriptor
|
||||
|
||||
fun libraryPath(): String = libraryJarDescriptor.jarName
|
||||
fun getLibFile(): File = libraryJarDescriptor.getPath(PathUtil.getKotlinPathsForIdeaPlugin())
|
||||
fun getLibFile(): File = libraryJarDescriptor.getPathInPlugin()
|
||||
fun hasLibJarInLibrary(library: Library): Boolean = libraryJarDescriptor.findExistingJar(library) != null
|
||||
|
||||
class MavenExternalLibraryDescriptor(groupId: String, artifactId: String, version: String) :
|
||||
|
||||
@@ -171,7 +171,7 @@ fun checkUpdateRuntime(project: Project, requiredVersion: ApiVersion): Boolean {
|
||||
}
|
||||
if (modulesWithOutdatedRuntime.isNotEmpty()) {
|
||||
if (!askUpdateRuntime(project, requiredVersion,
|
||||
modulesWithOutdatedRuntime.mapNotNull(::findKotlinRuntimeLibrary))) return false
|
||||
modulesWithOutdatedRuntime.mapNotNull { findKotlinRuntimeLibrary(it) })) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -120,8 +120,7 @@ private fun updateJar(
|
||||
}
|
||||
|
||||
val oldUrl = fileToReplace?.url
|
||||
val paths = PathUtil.getKotlinPathsForIdeaPlugin()
|
||||
val jarPath: File = libraryJarDescriptor.getPath(paths)
|
||||
val jarPath: File = libraryJarDescriptor.getPathInPlugin()
|
||||
|
||||
if (!jarPath.exists()) {
|
||||
showRuntimeJarNotFoundDialog(project, libraryJarDescriptor.jarName)
|
||||
@@ -185,6 +184,8 @@ enum class LibraryJarDescriptor(val jarName: String,
|
||||
if (isExternalLibrary(library)) return null
|
||||
return LibraryUtils.getJarFile(Arrays.asList(*library.getFiles(orderRootType)), jarName)
|
||||
}
|
||||
|
||||
fun getPathInPlugin() = getPath(PathUtil.getKotlinPathsForIdeaPlugin())
|
||||
}
|
||||
|
||||
fun bundledRuntimeVersion(): String {
|
||||
|
||||
@@ -26,14 +26,12 @@ import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.util.PathUtil.getLocalFile
|
||||
import com.intellij.util.text.VersionComparatorUtil
|
||||
import org.jetbrains.kotlin.idea.KotlinPluginUtil
|
||||
import org.jetbrains.kotlin.idea.framework.JSLibraryStdPresentationProvider
|
||||
import org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider
|
||||
import org.jetbrains.kotlin.idea.framework.getLibraryProperties
|
||||
import org.jetbrains.kotlin.idea.framework.isDetected
|
||||
import org.jetbrains.kotlin.idea.framework.*
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import java.io.IOException
|
||||
import javax.swing.event.HyperlinkEvent
|
||||
@@ -74,13 +72,21 @@ private fun getKotlinLibraryVersionProperties(library: Library) =
|
||||
getLibraryProperties(JavaRuntimePresentationProvider.getInstance(), library) ?:
|
||||
getLibraryProperties(JSLibraryStdPresentationProvider.getInstance(), library)
|
||||
|
||||
fun findKotlinRuntimeLibrary(module: Module): Library? {
|
||||
fun findKotlinRuntimeLibrary(module: Module, predicate: (Library) -> Boolean = ::isKotlinRuntime): Library? {
|
||||
val orderEntries = ModuleRootManager.getInstance(module).orderEntries.filterIsInstance<LibraryOrderEntry>()
|
||||
return orderEntries.asSequence()
|
||||
.mapNotNull { it.library }
|
||||
.firstOrNull { getKotlinLibraryVersionProperties(it) != null }
|
||||
.firstOrNull(predicate)
|
||||
}
|
||||
|
||||
fun isKotlinRuntime(library: Library) = isKotlinJavaRuntime(library) || isKotlinJsRuntime(library)
|
||||
|
||||
fun isKotlinJavaRuntime(library: Library) =
|
||||
JavaRuntimeDetectionUtil.getRuntimeJar(library.getFiles(OrderRootType.CLASSES).asList()) != null
|
||||
|
||||
fun isKotlinJsRuntime(library: Library) =
|
||||
JsLibraryStdDetectionUtil.getJsStdLibJar(library.getFiles(OrderRootType.CLASSES).asList()) != null
|
||||
|
||||
fun collectModulesWithOutdatedRuntime(libraries: List<VersionedLibrary>): List<Module> =
|
||||
libraries.flatMap { it.usedInModules }
|
||||
|
||||
|
||||
+19
-13
@@ -20,10 +20,12 @@ 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.roots.libraries.Library;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.testFramework.PlatformTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor;
|
||||
import org.jetbrains.kotlin.utils.PathUtil;
|
||||
|
||||
import java.io.File;
|
||||
@@ -32,7 +34,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigurator.FileState;
|
||||
import static org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigurator.LibraryState;
|
||||
|
||||
public abstract class AbstractConfigureKotlinTest extends PlatformTestCase {
|
||||
private static final String BASE_PATH = "idea/testData/configuration/";
|
||||
@@ -53,16 +54,22 @@ public abstract class AbstractConfigureKotlinTest extends PlatformTestCase {
|
||||
private static void configure(
|
||||
@NotNull List<Module> modules,
|
||||
@NotNull FileState runtimeState,
|
||||
@NotNull LibraryState libraryState,
|
||||
@NotNull KotlinWithLibraryConfigurator configurator,
|
||||
@NotNull String jarFromDist,
|
||||
@NotNull String jarFromTemp
|
||||
) {
|
||||
Project project = modules.iterator().next().getProject();
|
||||
NotificationMessageCollector collector = NotificationMessageCollectorKt.createConfigureKotlinNotificationCollector(project);
|
||||
|
||||
for (Module module : modules) {
|
||||
Library library = configurator.getKotlinLibrary(module);
|
||||
if (library == null) {
|
||||
library = configurator.createNewLibrary(project, collector);
|
||||
}
|
||||
String pathToJar = getPathToJar(runtimeState, jarFromDist, jarFromTemp);
|
||||
configurator.configureModuleWithLibraryClasses(module, libraryState, runtimeState, pathToJar, collector);
|
||||
for (LibraryJarDescriptor descriptor : configurator.getLibraryJarDescriptors()) {
|
||||
configurator.configureLibraryJar(module, library, runtimeState, pathToJar, descriptor, collector);
|
||||
}
|
||||
}
|
||||
collector.showNotification();
|
||||
}
|
||||
@@ -80,14 +87,14 @@ public abstract class AbstractConfigureKotlinTest extends PlatformTestCase {
|
||||
return jarFromDist;
|
||||
}
|
||||
|
||||
protected static void configure(@NotNull Module module, @NotNull FileState jarState, @NotNull LibraryState libraryState, @NotNull KotlinProjectConfigurator configurator) {
|
||||
protected static void configure(@NotNull Module module, @NotNull FileState jarState, @NotNull KotlinProjectConfigurator configurator) {
|
||||
if (configurator instanceof KotlinJavaModuleConfigurator) {
|
||||
configure(Collections.singletonList(module), jarState, libraryState,
|
||||
configure(Collections.singletonList(module), jarState,
|
||||
(KotlinWithLibraryConfigurator) configurator,
|
||||
getPathToExistentRuntimeJar(), getPathToNonexistentRuntimeJar());
|
||||
}
|
||||
if (configurator instanceof KotlinJsModuleConfigurator) {
|
||||
configure(Collections.singletonList(module), jarState, libraryState,
|
||||
configure(Collections.singletonList(module), jarState,
|
||||
(KotlinWithLibraryConfigurator) configurator,
|
||||
getPathToExistentJsJar(), getPathToNonexistentJsJar());
|
||||
}
|
||||
@@ -174,20 +181,19 @@ public abstract class AbstractConfigureKotlinTest extends PlatformTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
protected void doTestOneJavaModule(@NotNull FileState jarState, @NotNull LibraryState libraryState) {
|
||||
doTestOneModule(jarState, libraryState, JAVA_CONFIGURATOR);
|
||||
protected void doTestOneJavaModule(@NotNull FileState jarState) {
|
||||
doTestOneModule(jarState, JAVA_CONFIGURATOR);
|
||||
}
|
||||
|
||||
protected void doTestOneJsModule(@NotNull FileState jarState, @NotNull LibraryState libraryState) {
|
||||
doTestOneModule(jarState, libraryState, JS_CONFIGURATOR);
|
||||
protected void doTestOneJsModule(@NotNull FileState jarState) {
|
||||
doTestOneModule(jarState, JS_CONFIGURATOR);
|
||||
}
|
||||
|
||||
private void doTestOneModule(@NotNull FileState jarState, @NotNull LibraryState libraryState, @NotNull KotlinWithLibraryConfigurator configurator) {
|
||||
private void doTestOneModule(@NotNull FileState jarState, @NotNull KotlinWithLibraryConfigurator configurator) {
|
||||
Module module = getModule();
|
||||
assertEquals("Library state loaded from project files should be " + libraryState, libraryState, configurator.getLibraryState(module.getProject()));
|
||||
|
||||
assertNotConfigured(module, configurator);
|
||||
configure(module, jarState, libraryState, configurator);
|
||||
configure(module, jarState, configurator);
|
||||
assertProperlyConfigured(module, configurator);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,37 +34,27 @@ import java.util.Collections;
|
||||
|
||||
public class ConfigureKotlinTest extends AbstractConfigureKotlinTest {
|
||||
public void testNewLibrary_copyJar() {
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY, KotlinWithLibraryConfigurator.LibraryState.NEW_LIBRARY);
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY);
|
||||
}
|
||||
|
||||
public void testNewLibrary_doNotCopyJar() {
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, KotlinWithLibraryConfigurator.LibraryState.NEW_LIBRARY);
|
||||
}
|
||||
|
||||
public void testLibrary_doNotCopyJar() {
|
||||
try {
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, KotlinWithLibraryConfigurator.LibraryState.LIBRARY);
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
return;
|
||||
}
|
||||
fail("Test should throw IllegalStateException");
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY);
|
||||
}
|
||||
|
||||
public void testLibraryWithoutPaths_jarExists() {
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.EXISTS, KotlinWithLibraryConfigurator.LibraryState.NON_CONFIGURED_LIBRARY);
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.EXISTS);
|
||||
}
|
||||
|
||||
public void testNewLibrary_jarExists() {
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.EXISTS, KotlinWithLibraryConfigurator.LibraryState.NEW_LIBRARY);
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.EXISTS);
|
||||
}
|
||||
|
||||
public void testLibraryWithoutPaths_copyJar() {
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY, KotlinWithLibraryConfigurator.LibraryState.NON_CONFIGURED_LIBRARY);
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY);
|
||||
}
|
||||
|
||||
public void testLibraryWithoutPaths_doNotCopyJar() {
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, KotlinWithLibraryConfigurator.LibraryState.NON_CONFIGURED_LIBRARY);
|
||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@@ -72,12 +62,12 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest {
|
||||
Module[] modules = getModules();
|
||||
for (Module module : modules) {
|
||||
if (module.getName().equals("module1")) {
|
||||
configure(module, KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, KotlinWithLibraryConfigurator.LibraryState.NEW_LIBRARY, JAVA_CONFIGURATOR);
|
||||
configure(module, KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, JAVA_CONFIGURATOR);
|
||||
assertConfigured(module, JAVA_CONFIGURATOR);
|
||||
}
|
||||
else if (module.getName().equals("module2")) {
|
||||
assertNotConfigured(module, JAVA_CONFIGURATOR);
|
||||
configure(module, KotlinWithLibraryConfigurator.FileState.EXISTS, KotlinWithLibraryConfigurator.LibraryState.LIBRARY, JAVA_CONFIGURATOR);
|
||||
configure(module, KotlinWithLibraryConfigurator.FileState.EXISTS, JAVA_CONFIGURATOR);
|
||||
assertConfigured(module, JAVA_CONFIGURATOR);
|
||||
}
|
||||
}
|
||||
@@ -107,37 +97,27 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest {
|
||||
}
|
||||
|
||||
public void testNewLibrary_jarExists_js() {
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.EXISTS, KotlinWithLibraryConfigurator.LibraryState.NEW_LIBRARY);
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.EXISTS);
|
||||
}
|
||||
|
||||
public void testNewLibrary_copyJar_js() {
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.COPY, KotlinWithLibraryConfigurator.LibraryState.NEW_LIBRARY);
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.COPY);
|
||||
}
|
||||
|
||||
public void testNewLibrary_doNotCopyJar_js() {
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, KotlinWithLibraryConfigurator.LibraryState.NEW_LIBRARY);
|
||||
}
|
||||
|
||||
public void testJsLibrary_doNotCopyJar() {
|
||||
try {
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, KotlinWithLibraryConfigurator.LibraryState.LIBRARY);
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
return;
|
||||
}
|
||||
fail("Test should throw IllegalStateException");
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY);
|
||||
}
|
||||
|
||||
public void testJsLibraryWithoutPaths_jarExists() {
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.EXISTS, KotlinWithLibraryConfigurator.LibraryState.NON_CONFIGURED_LIBRARY);
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.EXISTS);
|
||||
}
|
||||
|
||||
public void testJsLibraryWithoutPaths_copyJar() {
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.COPY, KotlinWithLibraryConfigurator.LibraryState.NON_CONFIGURED_LIBRARY);
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.COPY);
|
||||
}
|
||||
|
||||
public void testJsLibraryWithoutPaths_doNotCopyJar() {
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, KotlinWithLibraryConfigurator.LibraryState.NON_CONFIGURED_LIBRARY);
|
||||
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY);
|
||||
}
|
||||
|
||||
public void testProjectWithoutFacetWithRuntime106WithoutLanguageLevel() {
|
||||
|
||||
Reference in New Issue
Block a user