IDEA-296526 Work around new Kotlin backend bug

GitOrigin-RevId: 7db562d99f008d38038ba246d59899af54b9e896
This commit is contained in:
Sebastiano Poggi
2022-06-23 14:47:50 +02:00
committed by intellij-monorepo-bot
parent cab26477e9
commit 5d13144d3b
28 changed files with 188 additions and 132 deletions

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="package-search-api-models">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/pkgs-api-models-2.2.8.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/pkgs-api-models-2.2.8-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="package-search-version-utils">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/pkgs-version-utils-1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/pkgs-version-utils-1.0.1-sources.jar!/" />
</SOURCES>
</library>
</component>

1
.idea/modules.xml generated
View File

@@ -750,6 +750,7 @@
<module fileurl="file://$PROJECT_DIR$/platform/built-in-server/client/node-rpc-client/intellij.nodeRpcClient.iml" filepath="$PROJECT_DIR$/platform/built-in-server/client/node-rpc-client/intellij.nodeRpcClient.iml" />
<module fileurl="file://$PROJECT_DIR$/notebooks/visualization/intellij.notebooks.visualization.iml" filepath="$PROJECT_DIR$/notebooks/visualization/intellij.notebooks.visualization.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/package-search/intellij.packageSearch.iml" filepath="$PROJECT_DIR$/plugins/package-search/intellij.packageSearch.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/package-search/compat/intellij.packageSearch.compat.iml" filepath="$PROJECT_DIR$/plugins/package-search/compat/intellij.packageSearch.compat.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/package-search/gradle/intellij.packageSearch.gradle.iml" filepath="$PROJECT_DIR$/plugins/package-search/gradle/intellij.packageSearch.gradle.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/package-search/kotlin/intellij.packageSearch.kotlin.iml" filepath="$PROJECT_DIR$/plugins/package-search/kotlin/intellij.packageSearch.kotlin.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/package-search/maven/intellij.packageSearch.maven.iml" filepath="$PROJECT_DIR$/plugins/package-search/maven/intellij.packageSearch.maven.iml" />

View File

@@ -128,6 +128,7 @@ final class CommunityRepositoryModules {
withProjectLibrary("Gradle", LibraryPackMode.STANDALONE_SEPARATE)
},
plugin("intellij.packageSearch") {
withModule("intellij.packageSearch.compat")
withModule("intellij.packageSearch.gradle")
withModule("intellij.packageSearch.maven")
withModule("intellij.packageSearch.kotlin")

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 11" allPlatforms="JVM [11]" useProjectSettings="false">
<compilerSettings>
<option name="additionalArguments" value="-version -Xjvm-default=enable -Xuse-old-backend -Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi -Xopt-in=kotlin.ExperimentalStdlibApi -Xopt-in=kotlinx.coroutines.FlowPreview -Xopt-in=kotlin.time.ExperimentalTime" />
</compilerSettings>
<compilerArguments>
<option name="jvmTarget" value="11" />
<option name="languageVersion" value="1.5" />
<option name="apiVersion" value="1.5" />
<option name="pluginClasspaths">
<array>
<option value="$KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar" />
</array>
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="com.jetbrains.packagesearch" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
<orderEntry type="library" name="package-search-api-models" level="project" />
<orderEntry type="library" name="package-search-version-utils" level="project" />
<orderEntry type="module" module-name="intellij.platform.core" />
</component>
</module>

View File

@@ -0,0 +1 @@
packagesearch.ui.missingVersion=[not set]

View File

@@ -0,0 +1,31 @@
/**
* ****************************************************************************
* Copyright 2000-2022 JetBrains s.r.o. and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations
* under the License.
* ****************************************************************************
*/
package com.jetbrains.packagesearch.intellij.plugin
import com.intellij.DynamicBundle
import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.PropertyKey
private const val BUNDLE_NAME = "messages.packageSearchCompatBundle"
internal object PackageSearchCompatBundle : DynamicBundle(BUNDLE_NAME) {
@Nls
fun message(
@PropertyKey(resourceBundle = BUNDLE_NAME) key: String,
vararg params: Any
): String = getMessage(key, *params)
}

View File

@@ -17,7 +17,7 @@
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models
import com.intellij.util.text.VersionComparatorUtil
import com.jetbrains.packagesearch.intellij.plugin.PackageSearchBundle
import com.jetbrains.packagesearch.intellij.plugin.PackageSearchCompatBundle
import com.jetbrains.packagesearch.intellij.plugin.util.versionTokenPriorityProvider
import kotlinx.serialization.Serializable
import org.jetbrains.annotations.Nls
@@ -46,7 +46,7 @@ sealed class PackageVersion : Comparable<PackageVersion> {
override val releasedAt: Long? = null
@Nls
override val displayName = PackageSearchBundle.message("packagesearch.ui.missingVersion")
override val displayName = PackageSearchCompatBundle.message("packagesearch.ui.missingVersion")
@NonNls
override fun toString() = "[Missing version]"
@@ -70,14 +70,14 @@ sealed class PackageVersion : Comparable<PackageVersion> {
@NonNls
override fun toString() = versionName
internal fun semanticVersionComponent(): SemVerComponent? {
fun semanticVersionComponent(): SemVerComponent? {
val groupValues = SEMVER_REGEX.find(versionName)?.groupValues ?: return null
if (groupValues.size <= 1) return null
val semanticVersion = groupValues[1].takeIf { it.isNotBlank() } ?: return null
return SemVerComponent(semanticVersion, this)
}
internal data class SemVerComponent(val semanticVersion: String, val named: Named)
data class SemVerComponent(val semanticVersion: String, val named: Named)
companion object {
@@ -87,7 +87,7 @@ sealed class PackageVersion : Comparable<PackageVersion> {
companion object {
internal fun from(rawVersion: ApiStandardPackage.ApiStandardVersion): PackageVersion {
fun from(rawVersion: ApiStandardPackage.ApiStandardVersion): PackageVersion {
if (rawVersion.version.isBlank()) return Missing
return Named(versionName = rawVersion.version.trim(), isStable = rawVersion.stable, releasedAt = rawVersion.lastChanged)
}

View File

@@ -22,7 +22,7 @@ import com.jetbrains.packagesearch.intellij.plugin.util.versionTokenPriorityProv
import kotlinx.serialization.Serializable
@Serializable
internal sealed class NormalizedPackageVersion<T : PackageVersion>(
sealed class NormalizedPackageVersion<T : PackageVersion>(
val originalVersion: T
) : Comparable<NormalizedPackageVersion<*>> {
@@ -182,17 +182,4 @@ internal sealed class NormalizedPackageVersion<T : PackageVersion>(
val nonSemanticSuffix: String?
}
companion object {
suspend fun parseFrom(version: PackageVersion.Named, normalizer: PackageVersionNormalizer): NormalizedPackageVersion<PackageVersion.Named> =
normalizer.parse(version)
suspend fun <T : PackageVersion> parseFrom(version: T, normalizer: PackageVersionNormalizer): NormalizedPackageVersion<*> =
when (version) {
is PackageVersion.Missing -> Missing
is PackageVersion.Named -> parseFrom(version, normalizer)
else -> error("Unknown version type: ${version.javaClass.simpleName}")
}
}
}

View File

@@ -19,8 +19,7 @@ package com.jetbrains.packagesearch.intellij.plugin.util
import com.intellij.util.text.VersionComparatorUtil
/**
* Used as parameter for the [VersionComparatorUtil.compare] method, to include additional tokens into the
* comparison.
* Used as parameter for the [VersionComparatorUtil.compare] method, to include additional tokens in the comparison.
*
* We support the following stability tokens, in addition to the ones supported by [VersionComparatorUtil]:
* * For snapshot-level: `snapshots`, `s`, `p`, `develop`, `dev`

View File

@@ -20,17 +20,15 @@ import com.intellij.util.text.VersionComparatorUtil
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.versions.NormalizedPackageVersion
/**
* Compares two raw version names, best-effort. If at all possible, you should use the
* [NormalizedPackageVersion] to compare versions with a lot of additional heuristics,
* including prioritizing semantic version names over non-semantic ones.
* Compares two raw version names, best-effort. If at all possible, you should use the [NormalizedPackageVersion] to compare versions with a lot of
* additional heuristics, including prioritizing semantic version names over non-semantic ones.
*
* This expands on what [VersionComparatorUtil] provide, so you should prefer this to
* [VersionComparatorUtil.COMPARATOR].
* This expands on what [VersionComparatorUtil] provide, so you should prefer this to [VersionComparatorUtil.COMPARATOR].
*
* @see versionTokenPriorityProvider
* @see VersionComparatorUtil
*/
internal object VersionNameComparator : Comparator<String> {
object VersionNameComparator : Comparator<String> {
override fun compare(first: String?, second: String?): Int =
VersionComparatorUtil.compare(first, second, ::versionTokenPriorityProvider)

View File

@@ -27,17 +27,17 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="intellij.packageSearch" />
<orderEntry type="module" module-name="intellij.platform.projectModel.impl" />
<orderEntry type="module" module-name="intellij.gradle.common" />
<orderEntry type="module" module-name="intellij.platform.ide" />
<orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="module" module-name="intellij.platform.statistics" />
<orderEntry type="module" module-name="intellij.java.psi" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" />
<orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" />
<orderEntry type="module" module-name="intellij.gradle.toolingExtension.impl" />
<orderEntry type="library" name="kotlinx-serialization-json" level="project" />
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
<orderEntry type="module" module-name="intellij.gradle.common" />
<orderEntry type="module" module-name="intellij.gradle.toolingExtension.impl" />
<orderEntry type="module" module-name="intellij.java.psi" />
<orderEntry type="module" module-name="intellij.packageSearch" />
<orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" />
<orderEntry type="module" module-name="intellij.platform.ide" />
<orderEntry type="module" module-name="intellij.platform.projectModel.impl" />
<orderEntry type="module" module-name="intellij.platform.statistics" />
</component>
</module>

View File

@@ -4,12 +4,12 @@
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 11" allPlatforms="JVM [11]" useProjectSettings="false">
<compilerSettings>
<option name="additionalArguments" value="-version -Xjvm-default=enable -Xuse-old-backend -Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi -Xopt-in=kotlin.ExperimentalStdlibApi -Xopt-in=kotlinx.coroutines.FlowPreview -Xopt-in=kotlin.time.ExperimentalTime" />
<option name="additionalArguments" value="-version -Xjvm-default=enable -Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi -Xopt-in=kotlin.ExperimentalStdlibApi -Xopt-in=kotlinx.coroutines.FlowPreview -Xopt-in=kotlin.time.ExperimentalTime" />
</compilerSettings>
<compilerArguments>
<option name="jvmTarget" value="11" />
<option name="languageVersion" value="1.5" />
<option name="apiVersion" value="1.5" />
<option name="languageVersion" value="1.7" />
<option name="apiVersion" value="1.7" />
<option name="pluginClasspaths">
<array>
<option value="$KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar" />
@@ -35,56 +35,35 @@
<orderEntry type="library" name="commons-lang3" level="project" />
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="library" name="http-client-3.1" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit5" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit5Params" level="project" />
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" />
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
<orderEntry type="library" name="kotlinx-serialization-json" level="project" />
<orderEntry type="library" name="miglayout-swing" level="project" />
<orderEntry type="library" name="netty-buffer" level="project" />
<orderEntry type="library" name="netty-codec-http" level="project" />
<orderEntry type="library" name="rd-core" level="project" />
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" />
<orderEntry type="library" name="package-search-api-models" level="project" />
<orderEntry type="library" name="package-search-version-utils" level="project" />
<orderEntry type="module" module-name="intellij.java.psi" />
<orderEntry type="module" module-name="intellij.packageSearch.compat" />
<orderEntry type="module" module-name="intellij.platform.analysis" />
<orderEntry type="module" module-name="intellij.platform.builtInServer.impl" />
<orderEntry type="module" module-name="intellij.platform.core" />
<orderEntry type="module" module-name="intellij.platform.core.impl" />
<orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="module" module-name="intellij.platform.editor" />
<orderEntry type="module" module-name="intellij.platform.externalSystem" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.impl" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" />
<orderEntry type="module" module-name="intellij.platform.ide.impl" />
<orderEntry type="module" module-name="intellij.platform.ide.util.io" />
<orderEntry type="module" module-name="intellij.platform.ide.util.netty" />
<orderEntry type="module" module-name="intellij.platform.lang" />
<orderEntry type="module" module-name="intellij.platform.lang.impl" />
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="module" module-name="intellij.platform.rd.community" />
<orderEntry type="module" module-name="intellij.platform.statistics" />
<orderEntry type="module" module-name="intellij.platform.util.ui" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" />
<orderEntry type="module" module-name="intellij.platform.ide.util.io" />
<orderEntry type="module" module-name="intellij.platform.ide.util.netty" />
<orderEntry type="module" module-name="intellij.platform.analysis" />
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
<orderEntry type="library" name="kotlinx-serialization-json" level="project" />
<orderEntry type="module-library">
<library name="package-search-version-utils">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/pkgs-version-utils-1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/lib/src/pkgs-version-utils-1.0.1-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="package-search-api-models">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/pkgs-api-models-2.2.8.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/lib/src/pkgs-api-models-2.2.8-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="library" scope="TEST" name="JUnit5" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit5Params" level="project" />
<orderEntry type="module" module-name="intellij.java.psi" />
<orderEntry type="module" module-name="intellij.platform.externalSystem" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.impl" />
<orderEntry type="module" module-name="intellij.platform.core.ui" />
</component>
</module>

View File

@@ -8,9 +8,9 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="intellij.platform.core" />
<orderEntry type="module" module-name="intellij.packageSearch" />
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="module" module-name="intellij.packageSearch" />
<orderEntry type="module" module-name="intellij.platform.analysis.impl" />
<orderEntry type="module" module-name="intellij.platform.core" />
</component>
</module>

View File

@@ -8,11 +8,11 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="intellij.packageSearch" />
<orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" />
<orderEntry type="module" module-name="intellij.maven" />
<orderEntry type="module" module-name="intellij.packageSearch" />
<orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" />
<orderEntry type="module" module-name="intellij.platform.projectModel.impl" />
<orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" />
</component>
</module>

View File

@@ -111,7 +111,6 @@ packagesearch.title=Package Search
packagesearch.ui.loading=Processing build files...
packagesearch.ui.missingScope=[default]
packagesearch.ui.missingVersion=[not set]
packagesearch.ui.toolwindow.actions.add.text=Add
packagesearch.ui.toolwindow.actions.remove.text=Remove

View File

@@ -34,4 +34,4 @@ object PackageSearchBundle : DynamicBundle(BUNDLE_NAME) {
@Nls
fun messagePointer(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String, vararg params: Any): Supplier<String> =
getLazyMessage(key, *params)
}
}

View File

@@ -32,7 +32,7 @@ inline fun <reified T, R> T.tryDoing(a: () -> R?): R? = try {
Logger.getInstance(T::class.java).error("Failed to execute safe operation: ${t.message}", t)
}
} catch (t: Throwable) {
// IntelliJ IDEA Logger may throw exception that we try to log inside
// IntelliJ IDEA Logger may throw an exception that we try to log inside
}
null
}

View File

@@ -49,7 +49,7 @@ internal suspend fun computePackageUpgrades(
val currentVersion = usageInfo.getResolvedVersionOrFallback()
if (currentVersion !is PackageVersion.Named) continue
val normalizedPackageVersion = runCatching { NormalizedPackageVersion.parseFrom(currentVersion, normalizer) }
val normalizedPackageVersion = runCatching { normalizer.parse(currentVersion) }
.onFailure { logError(throwable = it) { "Unable to normalize version: $currentVersion" } }
.getOrNull() ?: continue
@@ -77,7 +77,7 @@ internal suspend fun computePackageUpgrades(
return PackagesToUpgrade(updatesByModule)
}
internal suspend inline fun computeUpgradeOperationsForSingleModule(
internal inline fun computeUpgradeOperationsForSingleModule(
packageModel: PackageModel.Installed,
targetModule: ModuleModel,
knownRepositoriesInTargetModules: KnownRepositories.InTargetModules,

View File

@@ -81,13 +81,13 @@ internal sealed class PackageModel(
val latestInstalledVersion = async {
usageInfo.asFlow()
.map { it.declaredVersion }
.map { NormalizedPackageVersion.parseFrom(it, normalizer) }
.map { normalizer.parse(it) }
.toList()
.maxOrNull()
?: error("An installed package must always have at least one usage")
}
val declaredVersions = async {
usageInfo.map { it.declaredVersion }.map { NormalizedPackageVersion.parseFrom(it, normalizer) }
usageInfo.map { it.declaredVersion }.map { normalizer.parse(it) }
}
Installed(
groupId,
@@ -205,7 +205,7 @@ internal sealed class PackageModel(
remoteInfo?.versions?.asFlow()
?.map { PackageVersion.from(it) }
?.filterIsInstance<PackageVersion.Named>()
?.map { NormalizedPackageVersion.parseFrom(it, normalizer) }
?.map { normalizer.parse(it) }
?.toList()
?: emptyList()

View File

@@ -1,18 +1,19 @@
/*******************************************************************************
/**
* ****************************************************************************
* Copyright 2000-2022 JetBrains s.r.o. and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations
* under the License.
* ****************************************************************************
*/
@file:Suppress("UnusedReceiverParameter") // Used to namespace the functions
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models
@@ -22,18 +23,16 @@ import org.jetbrains.packagesearch.packageversionutils.PackageVersionUtils
import kotlin.math.sign
/**
* Determines the upgrade candidate version, if any exists in the [availableVersions] list, for [currentVersion].
* The main difference from the [highestSensibleVersionByNameOrNull] is that this makes sure whatever candidate
* it returns, if any, is "higher" than the [currentVersion], not only that it is the one with the highest version
* name in the list.
* Determines the upgrade candidate version, if any exists in the [availableVersions] list, for [currentVersion]. The main difference from the
* [highestSensibleVersionByNameOrNull] is that this makes sure whatever candidate it returns, if any, is "higher" than the [currentVersion], not only
* that it is the one with the highest version name in the list.
*
* If the current version is not a [NormalizedPackageVersion.Semantic], then the function returns the highest
* semantic version in the [availableVersions] list, if any.
* If the current version is not a [NormalizedPackageVersion.Semantic], then the function returns the highest semantic version in the
* [availableVersions] list, if any.
*
* If the current version is a [NormalizedPackageVersion.Semantic], then the function first tries to find a
* candidate with the same non-semantic suffix (which may be null/empty). If there is no candidate with the
* same suffix, it picks one without suffix. If there's no candidate without suffix, then it returns the one
* with the highest version name (and thus, the highest suffix).
* If the current version is a [NormalizedPackageVersion.Semantic], then the function first tries to find a candidate with the same non-semantic
* suffix (which may be null/empty). If there is no candidate with the same suffix, it picks one without suffix. If there's no candidate without
* suffix, then it returns the one with the highest version name (and thus, the highest suffix).
*
* If there's no candidate which satisfies the criteria, the function returns `null`.
*

View File

@@ -128,32 +128,29 @@ internal class PackageVersionNormalizer(
private val SEMVER_REGEX = "^((?:\\d{1,5}\\.){0,4}\\d{1,5}(?!\\.?\\d)).*\$".toRegex(option = RegexOption.IGNORE_CASE)
/**
* Extracts stability markers. Must be used on the string that follows a valid semver
* (see [SEMVER_REGEX]).
* Extracts stability markers. Must be used on the string that follows a valid semver (see [SEMVER_REGEX]).
*
* Stability markers are made up by a separator character (one of: . _ - +), then one of the
* stability tokens (see the list below), followed by an optional separator (one of: . _ -),
* AND [0, 5] numeric digits. After the digits, there must be a word boundary (most
* punctuation, except for underscores, qualifies as such).
* Stability markers are made up by a separator character (one of: . _ - +), then one of the stability tokens (see the list below), followed by an
* optional separator (one of: . _ -), AND [0, 5] numeric digits. After the digits, there must be a word boundary (most punctuation, except for
* underscores, qualifies as such).
*
* We only support up to two stability markers (arguably, having two already qualifies for
* the [Garbage] tier, but we have well-known libraries out there that do the two-markers
* game, now and then, and we need to support those shenanigans).
* We only support up to two stability markers (arguably, having two already qualifies for the [Garbage] tier, but we have well-known libraries
* out there that do the two-markers game, now and then, and we need to support those shenanigans).
*
* ### Stability tokens
* We support the following stability tokens:
* * `snapshots`*, `snapshot`, `snap`, `s`*
* * `preview`, `eap`, `pre`, `p`*
* * `develop`*, `dev`*
* * `milestone`*, `m`, `build`*
* * `alpha`, `a`
* * `betta` (yes, there are Bettas out there), `beta`, `b`
* * `candidate`*, `rc`
* * `sp`
* * `release`, `final`, `stable`*, `rel`, `r`
* * `snapshots`*, `snapshot`, `snap`, `s`*
* * `preview`, `eap`, `pre`, `p`*
* * `develop`*, `dev`*
* * `milestone`*, `m`, `build`*
* * `alpha`, `a`
* * `betta` (yes, there are Bettas out there), `beta`, `b`
* * `candidate`*, `rc`
* * `sp`
* * `release`, `final`, `stable`*, `rel`, `r`
*
* Tokens denoted by a `*` are considered as meaningless words by [com.intellij.util.text.VersionComparatorUtil]
* when comparing without a custom token priority provider, so sorting may be funky when they appear.
* Tokens denoted by a `*` are considered as meaningless words by [com.intellij.util.text.VersionComparatorUtil] when comparing without a custom
* token priority provider, so sorting may be funky when they appear.
*/
private val STABILITY_MARKER_REGEX =
("^((?:[._\\-+]" +
@@ -161,6 +158,13 @@ internal class PackageVersionNormalizer(
"(?:[._\\-]?\\d{1,5})?){1,2})(?:\\b|_)")
.toRegex(option = RegexOption.IGNORE_CASE)
suspend fun <T : PackageVersion> parse(version: T): NormalizedPackageVersion<*> =
when (version) {
is PackageVersion.Missing -> NormalizedPackageVersion.Missing
is PackageVersion.Named -> parse(version)
else -> error("Unknown version type: ${version.javaClass.simpleName}")
}
suspend fun parse(version: PackageVersion.Named): NormalizedPackageVersion<PackageVersion.Named> {
val cachedValue = versionsCache.get(version)

View File

@@ -16,7 +16,6 @@
package com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.versions.NormalizedPackageVersion
import com.jetbrains.packagesearch.intellij.plugin.ui.toolwindow.models.versions.PackageVersionNormalizer
import kotlinx.coroutines.runBlocking
@@ -38,6 +37,6 @@ internal object PackageVersionComparator : Comparator<PackageVersion> {
}
private fun compareNamed(first: PackageVersion.Named, second: PackageVersion.Named): Int {
return runBlocking { NormalizedPackageVersion.parseFrom(first, normalizer).compareTo(NormalizedPackageVersion.parseFrom(second, normalizer)) }
return runBlocking { normalizer.parse(first).compareTo(normalizer.parse(second)) }
}
}

View File

@@ -189,4 +189,4 @@ internal class NormalizedPackageVersionTest {
}
internal fun NormalizedPackageVersion.Companion.parseFromBlocking(version: PackageVersion.Named, normalizer: PackageVersionNormalizer) =
runBlocking { parseFrom(version, normalizer) }
runBlocking { normalizer.parse(version) }