code review
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
<implementation-class>org.jetbrains.kotlin.idea.compiler.KotlinCompilerManager</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.configuration.ui.NonConfiguredKotlinProjectComponent</implementation-class>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
|
||||
@@ -576,7 +576,7 @@
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanelProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.highlighter.ErrorDuringFileAnalyzeNotificationProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.configuration.KotlinSetupSDKNotificationProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.configuration.KotlinSetupEnvironmentNotificationProvider"/>
|
||||
|
||||
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.asJava.KotlinCodeBlockModificationListener"/>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<Module> = emptyList()): Collection<Module> {
|
||||
val modulesWithKotlinFiles = getModulesWithKotlinFiles(project) - excludeModules
|
||||
val ableToRunConfigurators = getAbleToRunConfigurators(project)
|
||||
return modulesWithKotlinFiles.filter { module ->
|
||||
getAbleToRunConfigurators(project).any { !it.isConfigured(module) }
|
||||
ableToRunConfigurators.any { !it.isConfigured(module) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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<EditorNotificationPanel>(), DumbAware {
|
||||
|
||||
+11
-6
@@ -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<Module> modulesWithOutdatedRuntime = OutdatedKotlinRuntimeNotificationKt.checkOutdatedKotlinRuntime(myProject);
|
||||
ConfigureKotlinInProjectUtilsKt.showConfigureKotlinNotificationIfNeeded(myProject, modulesWithOutdatedRuntime);
|
||||
List<VersionedLibrary> libraries = OutdatedKotlinRuntimeCheckerKt.findOutdatedKotlinLibraries(myProject);
|
||||
if (!libraries.isEmpty()) {
|
||||
OutdatedKotlinRuntimeCheckerKt.notifyOutdatedKotlinRuntime(myProject, libraries);
|
||||
}
|
||||
ConfigureKotlinInProjectUtilsKt.showConfigureKotlinNotificationIfNeeded(myProject,
|
||||
OutdatedKotlinRuntimeCheckerKt
|
||||
.collectModulesWithOutdatedRuntime(libraries));
|
||||
}
|
||||
});
|
||||
}
|
||||
+2
-2
@@ -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<Module> 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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ fun getLibraryRootsWithAbiIncompatibleKotlinClasses(module: Module): Collection<
|
||||
fun getLibraryRootsWithAbiIncompatibleForKotlinJs(module: Module): Collection<VirtualFile> {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
||||
+32
-35
@@ -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<Module>)
|
||||
|
||||
fun checkOutdatedKotlinRuntime(project: Project): List<Module> {
|
||||
fun findOutdatedKotlinLibraries(project: Project): List<VersionedLibrary> {
|
||||
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<Module> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val versionedOutdatedLibraries = findOutdatedKotlinLibraries(project)
|
||||
if (versionedOutdatedLibraries.isEmpty()) {
|
||||
return emptyList()
|
||||
val outdatedLibraries = arrayListOf<VersionedLibrary>()
|
||||
|
||||
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<VersionedLibrary>): List<Module> =
|
||||
libraries.flatMap { it.usedInModules }
|
||||
|
||||
fun notifyOutdatedKotlinRuntime(project: Project, outdatedLibraries: Collection<VersionedLibrary>) {
|
||||
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<Module> {
|
||||
"<p><a href=\"update\">Update Runtime</a> <a href=\"ignore\">Ignore</a></p>"
|
||||
}
|
||||
else {
|
||||
val libraryNames = versionedOutdatedLibraries.keys.joinToString { it.library.name!! }
|
||||
val libraryNames = outdatedLibraries.joinToString { it.library.name!! }
|
||||
|
||||
"<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>" +
|
||||
@@ -75,7 +97,7 @@ fun checkOutdatedKotlinRuntime(project: Project): List<Module> {
|
||||
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<Module> {
|
||||
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<VersionedLibrary, Collection<Module>> {
|
||||
val outdatedLibraries = hashMapOf<VersionedLibrary, Collection<Module>>()
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user