From 4d13e389484316c9ea9ca3390a2c79b99966a788 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Thu, 8 Mar 2018 00:08:05 +0300 Subject: [PATCH] Show warning alert when the installed Kotlin plugin version is incompatible with the IDE platform version --- .../idea/KotlinPluginCompatibilityVerifier.kt | 80 +++++++++++++++++++ .../kotlin/idea/PluginStartupComponent.java | 2 + ...patibilityVerifierVersionComparisonTest.kt | 23 ++++++ 3 files changed, 105 insertions(+) create mode 100644 idea/src/org/jetbrains/kotlin/idea/KotlinPluginCompatibilityVerifier.kt create mode 100644 idea/tests/org/jetbrains/kotlin/test/CompatibilityVerifierVersionComparisonTest.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/KotlinPluginCompatibilityVerifier.kt b/idea/src/org/jetbrains/kotlin/idea/KotlinPluginCompatibilityVerifier.kt new file mode 100644 index 00000000000..547d42f13fc --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/KotlinPluginCompatibilityVerifier.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea + +import com.intellij.openapi.application.ApplicationInfo +import com.intellij.openapi.ui.Messages +import com.intellij.util.PlatformUtils + +object KotlinPluginCompatibilityVerifier { + @JvmStatic + fun checkCompatibility() { + val kotlinVersion = KotlinPluginVersion.parse(KotlinPluginUtil.getPluginVersion()) ?: return + val platformVersion = PlatformVersion.getCurrent() ?: return + + if (kotlinVersion.platformVersion.platform != platformVersion.platform) { + Messages.showWarningDialog( + "Installed Kotlin plugin version ($kotlinVersion) is not compatible with $platformVersion.\n" + + "Some functionality may be broken.\n\n" + + "Please reinstall the Kotlin plugin.", + "Compatibility issue" + ) + } + } +} + +internal data class KotlinPluginVersion( + val kotlinVersion: String, // 1.2.3 + val status: String, // release, eap, rc + val buildNumber: String, // 53 + val platformVersion: PlatformVersion, + val patchNumber: String // usually '1' +) { + companion object { + private val KOTLIN_VERSION_REGEX = "^([\\d\\.]+)\\-([A-Za-z]+)\\-(\\d+)\\-([A-Za-z0-9\\.]+)\\-(\\d+)$".toRegex() + + fun parse(version: String): KotlinPluginVersion? { + val matchResult = KOTLIN_VERSION_REGEX.matchEntire(version) ?: return null + val (kotlinVersion, status, buildNumber, platformString, patchNumber) = matchResult.destructured + val platformVersion = PlatformVersion.parse(platformString) ?: return null + return KotlinPluginVersion(kotlinVersion, status, buildNumber, platformVersion, patchNumber) + } + } + + override fun toString() = "$kotlinVersion for $platformVersion" +} + +internal data class PlatformVersion(val platform: Platform, val version: String /* 3.1 or 2017.3 */) { + companion object { + fun parse(platformString: String): PlatformVersion? { + for (platform in Platform.values()) { + if (platformString.startsWith(platform.qualifier)) { + return PlatformVersion(platform, platformString.drop(platform.qualifier.length)) + } + } + + return null + } + + fun getCurrent(): PlatformVersion? { + val prefix = PlatformUtils.getPlatformPrefix() ?: return null + val platform = when (prefix) { + PlatformUtils.IDEA_CE_PREFIX, PlatformUtils.IDEA_PREFIX -> Platform.IDEA + "AndroidStudio" -> Platform.ANDROID_STUDIO // from 'com.android.tools.idea.IdeInfo' + else -> return null + } + + val version = ApplicationInfo.getInstance().run { majorVersion + "." + minorVersion.substringBefore(".") } + return PlatformVersion(platform, version) + } + } + + enum class Platform(val qualifier: String, val presentableText: String) { + IDEA("IJ", "IDEA"), ANDROID_STUDIO("Studio", "Android Studio") + } + + override fun toString() = platform.presentableText + " " + version +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java b/idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java index 33b7948c768..ed74e7aa2bb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java +++ b/idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java @@ -74,6 +74,8 @@ public class PluginStartupComponent implements ApplicationComponent { ServiceManager.getService(IndexPatternSearch.class).registerExecutor(new KotlinTodoSearcher()); + KotlinPluginCompatibilityVerifier.checkCompatibility(); + //todo[Sedunov]: wait for fix in platform to avoid misunderstood from Java newbies (also ConfigureKotlinInTempDirTest) //KotlinSdkType.Companion.setUpIfNeeded(); } diff --git a/idea/tests/org/jetbrains/kotlin/test/CompatibilityVerifierVersionComparisonTest.kt b/idea/tests/org/jetbrains/kotlin/test/CompatibilityVerifierVersionComparisonTest.kt new file mode 100644 index 00000000000..8a39238dd74 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/test/CompatibilityVerifierVersionComparisonTest.kt @@ -0,0 +1,23 @@ +package org.jetbrains.kotlin.test + +import com.intellij.testFramework.LightPlatformTestCase +import org.jetbrains.kotlin.idea.KotlinPluginVersion +import org.jetbrains.kotlin.idea.PlatformVersion + +class CompatibilityVerifierVersionComparisonTest : LightPlatformTestCase() { + fun testKotlinVersionParsing() { + val version = KotlinPluginVersion.parse("1.2.40-dev-193-Studio3.0-1") + ?: throw AssertionError("Version should not be null") + + assertEquals("1.2.40", version.kotlinVersion) + assertEquals("dev", version.status) + assertEquals("193", version.buildNumber) + assertEquals(PlatformVersion.Platform.ANDROID_STUDIO, version.platformVersion.platform) + assertEquals("3.0", version.platformVersion.version) + assertEquals("1", version.patchNumber) + } + + fun testPlatformVersionParsing() { + PlatformVersion.getCurrent() ?: throw AssertionError("Version should not be null") + } +} \ No newline at end of file