From 84d507b770d4c0438d7402f1bdcb500d574cc300 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 21 Jan 2016 12:39:20 +0100 Subject: [PATCH] code review --- idea/src/META-INF/plugin.xml | 4 +- .../idea/KotlinModuleTypeManagerImpl.java | 11 +-- .../actions/ConfigureKotlinInProjectAction.kt | 1 + .../ConfigureKotlinInProjectUtils.kt | 7 +- ...inSetupEnvironmentNotificationProvider.kt} | 2 +- ... KotlinConfigurationCheckerComponent.java} | 17 +++-- .../ConfigureKotlinNotification.java | 4 +- .../kotlin/idea/util/projectStructureUtil.kt | 10 ++- .../idea/versions/KotlinRuntimeLibraryUtil.kt | 2 +- ...ion.kt => OutdatedKotlinRuntimeChecker.kt} | 67 +++++++++---------- 10 files changed, 66 insertions(+), 59 deletions(-) rename idea/src/org/jetbrains/kotlin/idea/configuration/{KotlinSetupSDKNotificationProvider.kt => KotlinSetupEnvironmentNotificationProvider.kt} (99%) rename idea/src/org/jetbrains/kotlin/idea/configuration/ui/{NonConfiguredKotlinProjectComponent.java => KotlinConfigurationCheckerComponent.java} (68%) rename idea/src/org/jetbrains/kotlin/idea/versions/{OutdatedKotlinRuntimeNotification.kt => OutdatedKotlinRuntimeChecker.kt} (88%) diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index a4fcf4efa82..7d31a9851ae 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -23,7 +23,7 @@ org.jetbrains.kotlin.idea.compiler.KotlinCompilerManager - org.jetbrains.kotlin.idea.configuration.ui.NonConfiguredKotlinProjectComponent + org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory @@ -576,7 +576,7 @@ - + diff --git a/idea/src/org/jetbrains/kotlin/idea/KotlinModuleTypeManagerImpl.java b/idea/src/org/jetbrains/kotlin/idea/KotlinModuleTypeManagerImpl.java index 56a47a0ec26..3b38f9eadef 100644 --- a/idea/src/org/jetbrains/kotlin/idea/KotlinModuleTypeManagerImpl.java +++ b/idea/src/org/jetbrains/kotlin/idea/KotlinModuleTypeManagerImpl.java @@ -25,14 +25,15 @@ import org.jetbrains.kotlin.idea.configuration.KotlinModuleTypeManager; public class KotlinModuleTypeManagerImpl extends KotlinModuleTypeManager { @Override public boolean isAndroidGradleModule(@NotNull Module module) { - // We don't want to depend on the Android-Gradle plugin - // See com.android.tools.idea.gradle.util.Projects.isGradleProject() - boolean hasAndroidFacet = false; + return hasAndroidFacet(module) && isGradleModule(module); + } + + private static boolean hasAndroidFacet(@NotNull Module module) { for (Facet facet : FacetManager.getInstance(module).getAllFacets()) { if (facet.getName().equals("Android")) { - hasAndroidFacet = true; + return true; } } - return hasAndroidFacet && isGradleModule(module); + return false; } } diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/ConfigureKotlinInProjectAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/ConfigureKotlinInProjectAction.kt index a1f867ae19b..9b5851572a3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/ConfigureKotlinInProjectAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/ConfigureKotlinInProjectAction.kt @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.project.Project import com.intellij.openapi.ui.Messages import org.jetbrains.kotlin.idea.configuration.* +import org.jetbrains.kotlin.idea.util.projectStructure.allModules import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.utils.ifEmpty diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt index fd0b3cf7d6b..9babdd2b1f0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt @@ -21,11 +21,11 @@ import com.intellij.notification.NotificationType import com.intellij.notification.Notifications import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.psi.search.FileTypeIndex import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.idea.util.projectStructure.allModules import org.jetbrains.kotlin.utils.ifEmpty fun isProjectConfigured(project: Project): Boolean { @@ -33,8 +33,6 @@ fun isProjectConfigured(project: Project): Boolean { return modules.all { isModuleConfigured(it) } } -fun Project.allModules() = ModuleManager.getInstance(this).modules.toList() - fun isModuleConfigured(module: Module): Boolean { val configurators = getApplicableConfigurators(module) return configurators.any { it.isConfigured(module) } @@ -94,8 +92,9 @@ fun getNonConfiguredModulesWithKotlinFiles(project: Project, configurator: Kotli fun getNonConfiguredModules(project: Project, excludeModules: Collection = emptyList()): Collection { val modulesWithKotlinFiles = getModulesWithKotlinFiles(project) - excludeModules + val ableToRunConfigurators = getAbleToRunConfigurators(project) return modulesWithKotlinFiles.filter { module -> - getAbleToRunConfigurators(project).any { !it.isConfigured(module) } + ableToRunConfigurators.any { !it.isConfigured(module) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupSDKNotificationProvider.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt similarity index 99% rename from idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupSDKNotificationProvider.kt rename to idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt index 5c07442a28f..ef2a2ed2706 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupSDKNotificationProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt @@ -44,7 +44,7 @@ import org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanel import org.jetbrains.kotlin.idea.versions.createComponentActionLabel // Code is partially copied from com.intellij.codeInsight.daemon.impl.SetupSDKNotificationProvider -class KotlinSetupSDKNotificationProvider( +class KotlinSetupEnvironmentNotificationProvider( private val myProject: Project, notifications: EditorNotifications) : EditorNotifications.Provider(), DumbAware { diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/ui/NonConfiguredKotlinProjectComponent.java b/idea/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.java similarity index 68% rename from idea/src/org/jetbrains/kotlin/idea/configuration/ui/NonConfiguredKotlinProjectComponent.java rename to idea/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.java index 72d520de3cf..144b894adc2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/ui/NonConfiguredKotlinProjectComponent.java +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinConfigurationCheckerComponent.java @@ -19,19 +19,19 @@ package org.jetbrains.kotlin.idea.configuration.ui; import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationsConfiguration; import com.intellij.openapi.components.AbstractProjectComponent; -import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtilsKt; -import org.jetbrains.kotlin.idea.versions.OutdatedKotlinRuntimeNotificationKt; +import org.jetbrains.kotlin.idea.versions.OutdatedKotlinRuntimeCheckerKt; +import org.jetbrains.kotlin.idea.versions.VersionedLibrary; import java.util.List; -public class NonConfiguredKotlinProjectComponent extends AbstractProjectComponent { +public class KotlinConfigurationCheckerComponent extends AbstractProjectComponent { public static final String CONFIGURE_NOTIFICATION_GROUP_ID = "Configure Kotlin in Project"; - protected NonConfiguredKotlinProjectComponent(Project project) { + protected KotlinConfigurationCheckerComponent(Project project) { super(project); NotificationsConfiguration.getNotificationsConfiguration(). @@ -48,8 +48,13 @@ public class NonConfiguredKotlinProjectComponent extends AbstractProjectComponen DumbService.getInstance(myProject).smartInvokeLater(new Runnable() { @Override public void run() { - List modulesWithOutdatedRuntime = OutdatedKotlinRuntimeNotificationKt.checkOutdatedKotlinRuntime(myProject); - ConfigureKotlinInProjectUtilsKt.showConfigureKotlinNotificationIfNeeded(myProject, modulesWithOutdatedRuntime); + List libraries = OutdatedKotlinRuntimeCheckerKt.findOutdatedKotlinLibraries(myProject); + if (!libraries.isEmpty()) { + OutdatedKotlinRuntimeCheckerKt.notifyOutdatedKotlinRuntime(myProject, libraries); + } + ConfigureKotlinInProjectUtilsKt.showConfigureKotlinNotificationIfNeeded(myProject, + OutdatedKotlinRuntimeCheckerKt + .collectModulesWithOutdatedRuntime(libraries)); } }); } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/ui/notifications/ConfigureKotlinNotification.java b/idea/src/org/jetbrains/kotlin/idea/configuration/ui/notifications/ConfigureKotlinNotification.java index a8a43cb8b1a..443f82a5782 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/ui/notifications/ConfigureKotlinNotification.java +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/ui/notifications/ConfigureKotlinNotification.java @@ -26,7 +26,7 @@ import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtilsKt; import org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator; -import org.jetbrains.kotlin.idea.configuration.ui.NonConfiguredKotlinProjectComponent; +import org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent; import javax.swing.event.HyperlinkEvent; import java.util.Collection; @@ -41,7 +41,7 @@ public class ConfigureKotlinNotification extends Notification { @NotNull final Project project, @NotNull final List excludeModules ) { - super(NonConfiguredKotlinProjectComponent.CONFIGURE_NOTIFICATION_GROUP_ID, TITLE, getNotificationString(project,excludeModules), + super(KotlinConfigurationCheckerComponent.CONFIGURE_NOTIFICATION_GROUP_ID, TITLE, getNotificationString(project, excludeModules), NotificationType.WARNING, new NotificationListener() { @Override public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { diff --git a/idea/src/org/jetbrains/kotlin/idea/util/projectStructureUtil.kt b/idea/src/org/jetbrains/kotlin/idea/util/projectStructureUtil.kt index 33b1c935ae5..72bd6b70738 100644 --- a/idea/src/org/jetbrains/kotlin/idea/util/projectStructureUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/util/projectStructureUtil.kt @@ -16,12 +16,16 @@ package org.jetbrains.kotlin.idea.util.projectStructure -import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.project.Project import com.intellij.openapi.roots.OrderEnumerator -import java.io.File -import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.VfsUtil +import java.io.File + +fun Project.allModules() = ModuleManager.getInstance(this).modules.toList() fun Module.findLibrary(predicate: (Library) -> Boolean): Library? = OrderEnumerator.orderEntries(this).findLibrary(predicate) diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt index ae457f2d14b..f074777711e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt @@ -59,7 +59,7 @@ fun getLibraryRootsWithAbiIncompatibleKotlinClasses(module: Module): Collection< fun getLibraryRootsWithAbiIncompatibleForKotlinJs(module: Module): Collection { return getLibraryRootsWithAbiIncompatibleVersion( module, KotlinJavaScriptAbiVersionIndex, - { version -> !KotlinJavascriptMetadataUtils.isAbiVersionCompatible(version.minor) }) // TODO: support major.minor.patch version in JS metadata + { version -> !KotlinJavascriptMetadataUtils.isAbiVersionCompatible(version.minor) }) // TODO: support major.minor.patch version in JS metadata } diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeNotification.kt b/idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeChecker.kt similarity index 88% rename from idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeNotification.kt rename to idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeChecker.kt index c1105338e43..c407cb2bfbd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeNotification.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/OutdatedKotlinRuntimeChecker.kt @@ -35,9 +35,9 @@ import org.jetbrains.kotlin.idea.util.application.runWriteAction import java.io.IOException import javax.swing.event.HyperlinkEvent -private data class VersionedLibrary(val library: Library, val version: String?) +data class VersionedLibrary(val library: Library, val version: String?, val usedInModules: Collection) -fun checkOutdatedKotlinRuntime(project: Project): List { +fun findOutdatedKotlinLibraries(project: Project): List { val pluginVersion = KotlinPluginUtil.getPluginVersion() if ("@snapshot@" == pluginVersion) return emptyList() // plugin is run from sources, can't compare versions @@ -46,13 +46,35 @@ fun checkOutdatedKotlinRuntime(project: Project): List { return emptyList() } - val versionedOutdatedLibraries = findOutdatedKotlinLibraries(project) - if (versionedOutdatedLibraries.isEmpty()) { - return emptyList() + val outdatedLibraries = arrayListOf() + + for ((library, modules) in findAllUsedLibraries(project).entrySet()) { + val libraryVersionProperties = + LibraryPresentationProviderUtil.getLibraryProperties(JavaRuntimePresentationProvider.getInstance(), library) ?: + LibraryPresentationProviderUtil.getLibraryProperties(JSLibraryStdPresentationProvider.getInstance(), library) ?: + continue + + val libraryVersion = libraryVersionProperties.versionString + + val runtimeVersion = bundledRuntimeVersion() + + val isOutdated = isRuntimeOutdated(libraryVersion, runtimeVersion) + + if (isOutdated) { + outdatedLibraries.add(VersionedLibrary(library, libraryVersion, modules)) + } } - val message: String = if (versionedOutdatedLibraries.size == 1) { - val versionedLibrary = versionedOutdatedLibraries.keys.first() + return outdatedLibraries +} + +fun collectModulesWithOutdatedRuntime(libraries: List): List = + libraries.flatMap { it.usedInModules } + +fun notifyOutdatedKotlinRuntime(project: Project, outdatedLibraries: Collection) { + val pluginVersion = KotlinPluginUtil.getPluginVersion() + val message: String = if (outdatedLibraries.size == 1) { + val versionedLibrary = outdatedLibraries.first() val version = versionedLibrary.version val readableVersion = version ?: "unknown" @@ -63,7 +85,7 @@ fun checkOutdatedKotlinRuntime(project: Project): List { "

Update Runtime Ignore

" } else { - val libraryNames = versionedOutdatedLibraries.keys.joinToString { it.library.name!! } + val libraryNames = outdatedLibraries.joinToString { it.library.name!! } "

Version of Kotlin runtime is outdated in several libraries ($libraryNames). Plugin version is $pluginVersion.

" + "

Runtime libraries should be updated to avoid compatibility problems.

" + @@ -75,7 +97,7 @@ fun checkOutdatedKotlinRuntime(project: Project): List { NotificationType.WARNING, NotificationListener { notification, event -> if (event.eventType == HyperlinkEvent.EventType.ACTIVATED) { if ("update" == event.description) { - val outdatedLibraries = findOutdatedKotlinLibraries(project).map { it.key.library } + val outdatedLibraries = findOutdatedKotlinLibraries(project).map { it.library } updateLibraries(project, outdatedLibraries) suggestDeleteKotlinJsIfNeeded(project, outdatedLibraries) } @@ -88,11 +110,9 @@ fun checkOutdatedKotlinRuntime(project: Project): List { notification.expire() } }), project) - - return versionedOutdatedLibraries.flatMap { it.value } } -private fun deleteKotlinJs(project: Project) { +fun deleteKotlinJs(project: Project) { ApplicationManager.getApplication().invokeLater { runWriteAction { val kotlinJsFile = project.baseDir.findFileByRelativePath("script/kotlin.js") ?: return@runWriteAction @@ -152,29 +172,6 @@ private fun suggestDeleteKotlinJsIfNeeded(project: Project, outdatedLibraries: C private val SUPPRESSED_PROPERTY_NAME = "oudtdated.runtime.suppressed.plugin.version" private val OUTDATED_RUNTIME_GROUP_DISPLAY_ID = "Outdated Kotlin Runtime" -private fun findOutdatedKotlinLibraries(project: Project): Map> { - val outdatedLibraries = hashMapOf>() - - for ((library, modules) in findAllUsedLibraries(project).entrySet()) { - val libraryVersionProperties = - LibraryPresentationProviderUtil.getLibraryProperties(JavaRuntimePresentationProvider.getInstance(), library) ?: - LibraryPresentationProviderUtil.getLibraryProperties(JSLibraryStdPresentationProvider.getInstance(), library) ?: - continue - - val libraryVersion = libraryVersionProperties.versionString - - val runtimeVersion = bundledRuntimeVersion() - - val isOutdated = isRuntimeOutdated(libraryVersion, runtimeVersion) - - if (isOutdated) { - outdatedLibraries[VersionedLibrary(library, libraryVersion)] = modules - } - } - - return outdatedLibraries -} - fun isRuntimeOutdated(libraryVersion: String?, runtimeVersion: String): Boolean { return libraryVersion == null || libraryVersion.startsWith("internal-") != runtimeVersion.startsWith("internal-") || VersionComparatorUtil.compare(runtimeVersion, libraryVersion) > 0