Minor: reformat, and warning fixes in outdated notification subsystem

This commit is contained in:
Nikolay Krasko
2018-01-09 18:45:00 +03:00
parent 2386cfbd07
commit b701117ffb
7 changed files with 171 additions and 150 deletions
@@ -22,7 +22,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType
import org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent
class KotlinExternalSystemSyncListener : ExternalSystemTaskNotificationListenerAdapter() {
override fun onStart(id: ExternalSystemTaskId) {
override fun onStart(id: ExternalSystemTaskId, workingDir: String) {
if (id.type == ExternalSystemTaskType.RESOLVE_PROJECT) {
id.findProject()?.let { project ->
KotlinConfigurationCheckerComponent.getInstance(project).syncStarted()
@@ -23,6 +23,7 @@ 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.impl.libraries.LibraryEx
import com.intellij.openapi.roots.libraries.Library
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
@@ -31,13 +32,13 @@ import org.jetbrains.kotlin.config.TargetPlatformKind
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
import org.jetbrains.kotlin.idea.facet.initializeIfNeeded
import org.jetbrains.kotlin.idea.framework.JavaRuntimeDetectionUtil
import org.jetbrains.kotlin.idea.framework.JavaRuntimeLibraryDescription
import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
import org.jetbrains.kotlin.idea.util.projectStructure.sdk
import org.jetbrains.kotlin.idea.util.projectStructure.version
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
@@ -73,12 +74,13 @@ open class KotlinJavaModuleConfigurator protected constructor() : KotlinWithLibr
override fun getLibraryJarDescriptors(sdk: Sdk?): List<LibraryJarDescriptor> {
var result = listOf(
LibraryJarDescriptor.RUNTIME_JAR,
LibraryJarDescriptor.RUNTIME_SRC_JAR,
LibraryJarDescriptor.REFLECT_JAR,
LibraryJarDescriptor.REFLECT_SRC_JAR,
LibraryJarDescriptor.TEST_JAR,
LibraryJarDescriptor.TEST_SRC_JAR)
LibraryJarDescriptor.RUNTIME_JAR,
LibraryJarDescriptor.RUNTIME_SRC_JAR,
LibraryJarDescriptor.REFLECT_JAR,
LibraryJarDescriptor.REFLECT_SRC_JAR,
LibraryJarDescriptor.TEST_JAR,
LibraryJarDescriptor.TEST_SRC_JAR
)
val sdkVersion = sdk?.version ?: return result
if (sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7)) {
result += listOf(LibraryJarDescriptor.RUNTIME_JDK7_JAR, LibraryJarDescriptor.RUNTIME_JDK7_SOURCES_JAR)
@@ -90,8 +92,8 @@ open class KotlinJavaModuleConfigurator protected constructor() : KotlinWithLibr
return result
}
override val libraryMatcher: (Library) -> Boolean
get() = ::isKotlinJavaRuntime
override val libraryMatcher: (Library) -> Boolean =
{ library -> JavaRuntimeDetectionUtil.getRuntimeJar(library.getFiles(OrderRootType.CLASSES).asList()) != null }
override fun configureKotlinSettings(modules: List<Module>) {
val project = modules.firstOrNull()?.project ?: return
@@ -102,8 +104,7 @@ open class KotlinJavaModuleConfigurator protected constructor() : KotlinWithLibr
Kotlin2JvmCompilerArgumentsHolder.getInstance(project).update {
jvmTarget = "1.8"
}
}
else {
} else {
for (module in modules) {
val sdkVersion = module.sdk?.version
if (sdkVersion != null && sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_8)) {
@@ -118,19 +119,19 @@ open class KotlinJavaModuleConfigurator protected constructor() : KotlinWithLibr
}
override fun configureModule(
module: Module,
classesPath: String,
sourcesPath: String,
collector: NotificationMessageCollector,
forceJarState: FileState?,
useBundled: Boolean
module: Module,
classesPath: String,
sourcesPath: String,
collector: NotificationMessageCollector,
forceJarState: FileState?,
useBundled: Boolean
) {
super.configureModule(module, classesPath, sourcesPath, collector, forceJarState, useBundled)
addStdlibToJavaModuleInfo(module, collector)
}
companion object {
val NAME = "java"
const val NAME = "java"
val instance: KotlinJavaModuleConfigurator
get() = Extensions.findExtension(KotlinProjectConfigurator.EP_NAME, KotlinJavaModuleConfigurator::class.java)
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.idea.framework.JSLibraryType
import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor
import org.jetbrains.kotlin.idea.versions.isKotlinJsRuntime
import org.jetbrains.kotlin.js.JavaScript
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.resolve.TargetPlatform
@@ -60,10 +59,12 @@ open class KotlinJsModuleConfigurator : KotlinWithLibraryConfigurator() {
get() = JSLibraryStdDescription.JAVA_SCRIPT_LIBRARY_CREATION
override fun getLibraryJarDescriptors(sdk: Sdk?): List<LibraryJarDescriptor> =
listOf(LibraryJarDescriptor.JS_STDLIB_JAR,
LibraryJarDescriptor.JS_STDLIB_SRC_JAR)
listOf(
LibraryJarDescriptor.JS_STDLIB_JAR,
LibraryJarDescriptor.JS_STDLIB_SRC_JAR
)
override val libraryMatcher: (Library) -> Boolean = ::isKotlinJsRuntime
override val libraryMatcher: (Library) -> Boolean = { library -> JsLibraryStdDetectionUtil.hasJsStdlibJar(library) }
override val libraryType: LibraryType<DummyLibraryProperties>?
get() = JSLibraryType.getInstance()
@@ -37,10 +37,13 @@ import java.util.concurrent.atomic.AtomicInteger
class KotlinConfigurationCheckerComponent(project: Project) : AbstractProjectComponent(project) {
private val syncDepth = AtomicInteger()
@Volatile private var notificationPostponed = false
@Volatile
private var notificationPostponed = false
init {
NotificationsConfiguration.getNotificationsConfiguration().register(CONFIGURE_NOTIFICATION_GROUP_ID, NotificationDisplayType.STICKY_BALLOON, true)
NotificationsConfiguration.getNotificationsConfiguration()
.register(CONFIGURE_NOTIFICATION_GROUP_ID, NotificationDisplayType.STICKY_BALLOON, true)
val connection = project.messageBus.connect()
connection.subscribe(ProjectTopics.PROJECT_ROOTS, object : ModuleRootListener {
@@ -50,8 +53,10 @@ class KotlinConfigurationCheckerComponent(project: Project) : AbstractProjectCom
DumbService.getInstance(myProject).waitForSmartMode()
if (!isSyncing) {
notificationPostponed = false
showConfigureKotlinNotificationIfNeeded(myProject,
collectModulesWithOutdatedRuntime(findOutdatedKotlinLibraries(myProject)))
showConfigureKotlinNotificationIfNeeded(
myProject,
collectModulesWithOutdatedRuntime(findOutdatedKotlinLibraries(myProject))
)
}
}
}
@@ -81,8 +86,7 @@ class KotlinConfigurationCheckerComponent(project: Project) : AbstractProjectCom
if (!isSyncing) {
val excludeModules = collectModulesWithOutdatedRuntime(libraries)
showConfigureKotlinNotificationIfNeeded(myProject, excludeModules)
}
else {
} else {
notificationPostponed = true
}
}
@@ -100,9 +104,9 @@ class KotlinConfigurationCheckerComponent(project: Project) : AbstractProjectCom
}
companion object {
val CONFIGURE_NOTIFICATION_GROUP_ID = "Configure Kotlin in Project"
const val CONFIGURE_NOTIFICATION_GROUP_ID = "Configure Kotlin in Project"
fun getInstance(project: Project): KotlinConfigurationCheckerComponent
= project.getComponent(KotlinConfigurationCheckerComponent::class.java)
fun getInstance(project: Project): KotlinConfigurationCheckerComponent =
project.getComponent(KotlinConfigurationCheckerComponent::class.java)
}
}
@@ -27,15 +27,18 @@ fun updateLibraries(project: Project, libraries: Collection<Library>) {
"Automatic library version update for Maven and Gradle projects is currently unsupported. " +
"Please update your build scripts manually.",
"Update Kotlin Runtime Library",
Messages.getErrorIcon())
Messages.getErrorIcon()
)
return
}
val kJvmConfigurator = getConfiguratorByName(KotlinJavaModuleConfigurator.NAME) as KotlinJavaModuleConfigurator? ?:
error("Configurator with given name doesn't exists: " + KotlinJavaModuleConfigurator.NAME)
val kJvmConfigurator =
getConfiguratorByName(KotlinJavaModuleConfigurator.NAME) as KotlinJavaModuleConfigurator?
?: error("Configurator with given name doesn't exists: " + KotlinJavaModuleConfigurator.NAME)
val kJsConfigurator = getConfiguratorByName(KotlinJsModuleConfigurator.NAME) as KotlinJsModuleConfigurator? ?:
error("Configurator with given name doesn't exists: " + KotlinJsModuleConfigurator.NAME)
val kJsConfigurator =
getConfiguratorByName(KotlinJsModuleConfigurator.NAME) as KotlinJsModuleConfigurator?
?: error("Configurator with given name doesn't exists: " + KotlinJsModuleConfigurator.NAME)
val collector = createConfigureKotlinNotificationCollector(project)
val sdk = ProjectRootManager.getInstance(project).projectSdk
@@ -56,9 +59,10 @@ fun updateLibraries(project: Project, libraries: Collection<Library>) {
}
private fun updateJar(
project: Project,
library: Library,
libraryJarDescriptor: LibraryJarDescriptor) {
project: Project,
library: Library,
libraryJarDescriptor: LibraryJarDescriptor
) {
val fileToReplace = libraryJarDescriptor.findExistingJar(library)
if (fileToReplace == null && !libraryJarDescriptor.shouldExist) {
@@ -77,9 +81,11 @@ private fun updateJar(
val newVFile = try {
replaceFile(jarPath, jarFileToReplace)
} catch (e: IOException) {
Messages.showErrorDialog(project,
"Failed to update $jarPath: ${e.message}",
"Library update failed")
Messages.showErrorDialog(
project,
"Failed to update $jarPath: ${e.message}",
"Library update failed"
)
return
}
@@ -92,8 +98,7 @@ private fun updateJar(
}
val newRoot = JarFileSystem.getInstance().getJarRootForLocalFile(newVFile)!!
model.addRoot(newRoot, libraryJarDescriptor.orderRootType)
}
finally {
} finally {
model.commit()
}
}
@@ -57,7 +57,7 @@ fun findOutdatedKotlinLibraries(project: Project): List<VersionedLibrary> {
return outdatedLibraries
}
fun getOutdatedRuntimeLibraryVersion(library: Library): String? {
private fun getOutdatedRuntimeLibraryVersion(library: Library): String? {
val libraryVersion = getKotlinLibraryVersion(library) ?: return null
val runtimeVersion = bundledRuntimeVersion()
@@ -65,23 +65,22 @@ fun getOutdatedRuntimeLibraryVersion(library: Library): String? {
}
private fun getKotlinLibraryVersion(library: Library): String? =
JavaRuntimeDetectionUtil.getJavaRuntimeVersion(library) ?:
JsLibraryStdDetectionUtil.getJsLibraryStdVersion(library)
JavaRuntimeDetectionUtil.getJavaRuntimeVersion(library) ?: JsLibraryStdDetectionUtil.getJsLibraryStdVersion(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(predicate)
.mapNotNull { it.library }
.firstOrNull(predicate)
}
fun isKotlinRuntime(library: Library) = isKotlinJavaRuntime(library) || isKotlinJsRuntime(library)
private fun isKotlinRuntime(library: Library) = isKotlinJavaRuntime(library) || isKotlinJsRuntime(library)
fun isKotlinJavaRuntime(library: Library) =
JavaRuntimeDetectionUtil.getRuntimeJar(library.getFiles(OrderRootType.CLASSES).asList()) != null
private fun isKotlinJavaRuntime(library: Library) =
JavaRuntimeDetectionUtil.getRuntimeJar(library.getFiles(OrderRootType.CLASSES).asList()) != null
fun isKotlinJsRuntime(library: Library) =
JsLibraryStdDetectionUtil.hasJsStdlibJar(library)
private fun isKotlinJsRuntime(library: Library) =
JsLibraryStdDetectionUtil.hasJsStdlibJar(library)
fun collectModulesWithOutdatedRuntime(libraries: List<VersionedLibrary>): List<Module> =
libraries.flatMap { it.usedInModules }
@@ -96,46 +95,50 @@ fun notifyOutdatedKotlinRuntime(project: Project, outdatedLibraries: Collection<
val libraryName = versionedLibrary.library.name
"<p>Your version of Kotlin runtime in '$libraryName' library is $readableVersion, while plugin version is $pluginVersion.</p>" +
"<p>Runtime library should be updated to avoid compatibility problems.</p>" +
"<p><a href=\"update\">Update Runtime</a> <a href=\"ignore\">Ignore</a></p>"
}
else {
"<p>Runtime library should be updated to avoid compatibility problems.</p>" +
"<p><a href=\"update\">Update Runtime</a> <a href=\"ignore\">Ignore</a></p>"
} else {
val libraryNames = outdatedLibraries.joinToString { it.library.name ?: "unknown library" }
"<p>Version of Kotlin runtime is outdated in several libraries ($libraryNames). Plugin version is $pluginVersion.</p>" +
"<p>Runtime libraries should be updated to avoid compatibility problems.</p>" +
"<p><a href=\"update\">Update All</a> <a href=\"ignore\">Ignore</a></p>"
"<p>Runtime libraries should be updated to avoid compatibility problems.</p>" +
"<p><a href=\"update\">Update All</a> <a href=\"ignore\">Ignore</a></p>"
}
Notifications.Bus.notify(Notification(OUTDATED_RUNTIME_GROUP_DISPLAY_ID, "Outdated Kotlin Runtime", message,
NotificationType.WARNING, NotificationListener { notification, event ->
if (event.eventType == HyperlinkEvent.EventType.ACTIVATED) {
when {
"update" == event.description -> {
val outdatedLibraries = findOutdatedKotlinLibraries(project).map { it.library }
ApplicationManager.getApplication().invokeLater {
updateLibraries(project, outdatedLibraries)
Notifications.Bus.notify(
Notification(
OUTDATED_RUNTIME_GROUP_DISPLAY_ID, "Outdated Kotlin Runtime", message,
NotificationType.WARNING, NotificationListener { notification, event ->
if (event.eventType == HyperlinkEvent.EventType.ACTIVATED) {
when {
"update" == event.description -> {
val updatedOutdatedLibraries = findOutdatedKotlinLibraries(project).map { it.library }
ApplicationManager.getApplication().invokeLater {
updateLibraries(project, updatedOutdatedLibraries)
}
}
"ignore" == event.description -> {
if (!project.isDisposed) {
PropertiesComponent.getInstance(project).setValue(SUPPRESSED_PROPERTY_NAME, pluginVersion)
}
}
else -> {
throw AssertionError()
}
}
}
"ignore" == event.description -> {
if (!project.isDisposed) {
PropertiesComponent.getInstance(project).setValue(SUPPRESSED_PROPERTY_NAME, pluginVersion)
}
}
else -> {
throw AssertionError()
notification.expire()
}
}
notification.expire()
}
}), project)
),
project
)
}
private val SUPPRESSED_PROPERTY_NAME = "oudtdated.runtime.suppressed.plugin.version"
private val OUTDATED_RUNTIME_GROUP_DISPLAY_ID = "Outdated Kotlin Runtime"
private const val SUPPRESSED_PROPERTY_NAME = "oudtdated.runtime.suppressed.plugin.version"
private const val OUTDATED_RUNTIME_GROUP_DISPLAY_ID = "Outdated Kotlin Runtime"
fun isRuntimeOutdated(libraryVersion: String?, runtimeVersion: String): Boolean {
return libraryVersion == null || libraryVersion.startsWith("internal-") != runtimeVersion.startsWith("internal-") ||
VersionComparatorUtil.compare(runtimeVersion.substringBefore("-release-"), libraryVersion) > 0
VersionComparatorUtil.compare(runtimeVersion.substringBefore("-release-"), libraryVersion) > 0
}