diff --git a/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/KotlinToolingVersion.kt b/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/KotlinToolingVersion.kt index fe4e49a80a8..623eefc054d 100644 --- a/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/KotlinToolingVersion.kt +++ b/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/KotlinToolingVersion.kt @@ -11,8 +11,20 @@ import java.io.Serializable import java.util.* fun KotlinToolingVersion(kotlinVersionString: String): KotlinToolingVersion { - return KotlinToolingVersionOrNull(kotlinVersionString) - ?: throw IllegalArgumentException("Invalid Kotlin version: $kotlinVersionString") + fun throwInvalid(reason: String): Nothing = throw IllegalArgumentException("Invalid Kotlin version: $kotlinVersionString ($reason)") + + val baseVersion = kotlinVersionString.split("-", limit = 2)[0] + val classifier = kotlinVersionString.split("-", limit = 2).getOrNull(1) + + val baseVersionSplit = baseVersion.split(".") + if (!(baseVersionSplit.size == 2 || baseVersionSplit.size == 3)) throwInvalid("Expected 2 or 3 '.' separated parts") + + return KotlinToolingVersion( + major = baseVersionSplit[0].toIntOrNull() ?: throwInvalid("Failed parsing major version"), + minor = baseVersionSplit[1].toIntOrNull() ?: throwInvalid("Failed parsing minor version"), + patch = baseVersionSplit.getOrNull(2)?.let { it.toIntOrNull() ?: throwInvalid("Failed parsing patch version") } ?: 0, + classifier = classifier + ) } fun KotlinToolingVersion(kotlinVersion: KotlinVersion, classifier: String? = null): KotlinToolingVersion { @@ -20,18 +32,11 @@ fun KotlinToolingVersion(kotlinVersion: KotlinVersion, classifier: String? = nul } fun KotlinToolingVersionOrNull(kotlinVersionString: String): KotlinToolingVersion? { - val baseVersion = kotlinVersionString.split("-", limit = 2)[0] - val classifier = kotlinVersionString.split("-", limit = 2).getOrNull(1) - - val baseVersionSplit = baseVersion.split(".") - if (!(baseVersionSplit.size == 2 || baseVersionSplit.size == 3)) return null - - return KotlinToolingVersion( - major = baseVersionSplit[0].toIntOrNull() ?: return null, - minor = baseVersionSplit[1].toIntOrNull() ?: return null, - patch = baseVersionSplit.getOrNull(2)?.let { it.toIntOrNull() ?: return null } ?: 0, - classifier = classifier - ) + return try { + KotlinToolingVersion(kotlinVersionString) + } catch (t: IllegalArgumentException) { + null + } } class KotlinToolingVersion( diff --git a/libraries/tools/kotlin-tooling-core/src/test/kotlin/org/jetbrains/kotlin/tooling/core/KotlinToolingVersionTest.kt b/libraries/tools/kotlin-tooling-core/src/test/kotlin/org/jetbrains/kotlin/tooling/core/KotlinToolingVersionTest.kt index 2b40ceb0460..f863dcc1f60 100644 --- a/libraries/tools/kotlin-tooling-core/src/test/kotlin/org/jetbrains/kotlin/tooling/core/KotlinToolingVersionTest.kt +++ b/libraries/tools/kotlin-tooling-core/src/test/kotlin/org/jetbrains/kotlin/tooling/core/KotlinToolingVersionTest.kt @@ -222,7 +222,7 @@ class KotlinToolingVersionTest { assertBuildNumber(510, "1.6.20-pub-myWildcard1-510") assertBuildNumber(510, "1.6.20-some-510") assertBuildNumber(510, "1.6.20-aaa-a2-a3-510") - assertBuildNumber(null,"1.6.20-dev-myWildcard510") + assertBuildNumber(null, "1.6.20-dev-myWildcard510") /* dev with - in wildcards */ assertBuildNumber(510, "1.6.20-dev-google-pr-510") @@ -314,8 +314,10 @@ class KotlinToolingVersionTest { fun illegalVersionString() { assertFailsWith { KotlinToolingVersion("x") } assertFailsWith { KotlinToolingVersion("1.6.20.1") } + assertNull(KotlinToolingVersionOrNull("")) assertNull(KotlinToolingVersionOrNull("x")) assertNull(KotlinToolingVersionOrNull("1.6.20.1")) + assertNull(KotlinToolingVersionOrNull("1.6.20-x")) } private fun assertBuildNumber(buildNumber: Int?, version: String, message: String? = null) { @@ -332,7 +334,10 @@ class KotlinToolingVersionTest { "Parsing maturity is expected to be failed for `$version`${message?.let { ". $it" } ?: ""}") { KotlinToolingVersion(version) } - assertTrue("maturity" in exception.message.orEmpty().toLowerCase(), "Expected 'maturity' issue mentioned in error message") + assertTrue( + "maturity" in exception.message.orEmpty().toLowerCase(), + "Expected 'maturity' issue mentioned in error message. Found: ${exception.message}" + ) } else { assertEquals(maturity, KotlinToolingVersion(version).maturity, message) }