Wizard: do not use apache maven Version classes

This commit is contained in:
Ilya Kirillov
2020-03-07 19:13:05 +03:00
parent 377cdfdb2d
commit 51f71a4e33
7 changed files with 3 additions and 962 deletions
@@ -1,7 +1,5 @@
package org.jetbrains.kotlin.tools.projectWizard.core
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import org.jetbrains.kotlin.tools.projectWizard.settings.version.VersionRange
import java.io.IOException
abstract class Error {
@@ -61,11 +59,6 @@ data class ConfiguratorNotFoundError(val id: String) : Error() {
get() = "Module type `$id` was not found"
}
data class VersionIsNotInRangeError(val subject: String, val version: Version, val range: VersionRange) : Error() {
override val message: String
get() = "${subject.capitalize()}'s version $version is not in expected range $range"
}
data class ValidationError(val validationMessage: String) : Error() {
override val message: String
get() = validationMessage.capitalize()
@@ -2,34 +2,12 @@ package org.jetbrains.kotlin.tools.projectWizard.settings.version
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.version.maven.ArtifactVersion
import org.jetbrains.kotlin.tools.projectWizard.settings.version.maven.DefaultArtifactVersion
class Version private constructor(internal val mavenVersion: ArtifactVersion) : Comparable<Version>, DisplayableSettingItem {
override fun compareTo(other: Version): Int = mavenVersion.compareTo(other.mavenVersion)
override fun equals(other: Any?): Boolean = mavenVersion == other.safeAs<Version>()?.mavenVersion
override fun hashCode(): Int = mavenVersion.hashCode()
override fun toString(): String = mavenVersion.toString()
val major
get() = mavenVersion.majorVersion
val minor
get() = mavenVersion.minorVersion
val incremental
get() = mavenVersion.incrementalVersion
override val text: String
get() = toString()
override val greyText: String?
get() = null
data class Version(override val text: String) : DisplayableSettingItem {
override fun toString(): String = text
companion object {
fun fromString(string: String) = Version(
DefaultArtifactVersion(string)
)
fun fromComponents(major: Int, minor: Int, incremental: Int) =
fromString("$major.$minor.$incremental")
fun fromString(string: String) = Version(string)
val parser: Parser<Version> = valueParser { value, path ->
val (stringVersion) = value.parseAs<String>(path)
@@ -1,33 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.settings.version
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
import org.jetbrains.kotlin.tools.projectWizard.settings.version.maven.Restriction
class VersionRange private constructor(private val mavenRange: Restriction) {
constructor(
lowerBound: Version?,
isLowerBoundInclusive: Boolean,
upperBound: Version?,
isUpperBoundInclusive: Boolean
) : this(
Restriction(
lowerBound?.mavenVersion,
isLowerBoundInclusive,
upperBound?.mavenVersion,
isUpperBoundInclusive
)
)
operator fun contains(version: Version) = mavenRange.containsVersion(version.mavenVersion)
override fun equals(other: Any?): Boolean = mavenRange == other.safeAs<VersionRange>()?.mavenRange
override fun hashCode(): Int = mavenRange.hashCode()
override fun toString(): String = mavenRange.toString()
companion object {
val ALL = VersionRange(null, true, null, true)
}
}
operator fun Version.rangeTo(upper: Version): VersionRange =
VersionRange(this, true, upper, true)
@@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* http://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 org.jetbrains.kotlin.tools.projectWizard.settings.version.maven
/**
* Describes an artifact version in terms of its components, converts it to/from a string and
* compares two versions.
*
* @author [Brett Porter](mailto:brett@apache.org)
*/
interface ArtifactVersion : Comparable<ArtifactVersion?> {
val majorVersion: Int
val minorVersion: Int
val incrementalVersion: Int
val buildNumber: Int
val qualifier: String?
fun parseVersion(version: String)
}
@@ -1,574 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* http://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.
*/
@file:Suppress("NAME_SHADOWING")
package org.jetbrains.kotlin.tools.projectWizard.settings.version.maven
import org.jetbrains.kotlin.tools.projectWizard.settings.version.maven.ComparableVersion.Item.Companion.BIGINTEGER_ITEM
import org.jetbrains.kotlin.tools.projectWizard.settings.version.maven.ComparableVersion.Item.Companion.INT_ITEM
import org.jetbrains.kotlin.tools.projectWizard.settings.version.maven.ComparableVersion.Item.Companion.LIST_ITEM
import org.jetbrains.kotlin.tools.projectWizard.settings.version.maven.ComparableVersion.Item.Companion.LONG_ITEM
import org.jetbrains.kotlin.tools.projectWizard.settings.version.maven.ComparableVersion.Item.Companion.STRING_ITEM
import java.math.BigInteger
import java.util.*
/**
* Converted to Kotlin version of `org.apache.maven.artifact.versioning.ComparableVersion`
*
* Generic implementation of version comparison.
*
*
*
* Features:
*
* * mixing of '`-`' (hyphen) and '`.`' (dot) separators,
* * transition between characters and digits also constitutes a separator:
* `1.0alpha1 => [1, 0, alpha, 1]`
* * unlimited number of version components,
* * version components in the text can be digits or strings,
* * strings are checked for well-known qualifiers and the qualifier ordering is used for version ordering.
* Well-known qualifiers (case insensitive) are:
* * `alpha` or `a`
* * `beta` or `b`
* * `milestone` or `m`
* * `rc` or `cr`
* * `snapshot`
* * `(the empty string)` or `ga` or `final`
* * `sp`
*
* Unknown qualifiers are considered after known qualifiers, with lexical order (always case insensitive),
*
* * a hyphen usually precedes a qualifier, and is always less important than something preceded with a dot.
*
*
* @author [Kenney Westerhof](mailto:kenney@apache.org)
* @author [Hervé Boutemy](mailto:hboutemy@apache.org)
* @see ["Versioning" on Maven Wiki](https://cwiki.apache.org/confluence/display/MAVENOLD/Versioning)
*/
class ComparableVersion(version: String) : Comparable<ComparableVersion?> {
private var value: String? = null
var canonical: String? = null
get() {
if (field == null) {
field = items.toString()
}
return field
}
private set
private var items: ListItem? = null
private interface Item {
operator fun compareTo(item: Item?): Int
val type: Int
val isNull: Boolean
companion object {
const val INT_ITEM = 3
const val LONG_ITEM = 4
const val BIGINTEGER_ITEM = 0
const val STRING_ITEM = 1
const val LIST_ITEM = 2
}
}
/**
* Represents a numeric item in the version item list that can be represented with an int.
*/
private class IntItem : Item {
private val value: Int
private constructor() {
value = 0
}
internal constructor(str: String) {
value = str.toInt()
}
override val type: Int
get() = INT_ITEM
override val isNull: Boolean
get() = value == 0
override fun compareTo(item: Item?): Int {
return if (item == null) {
if (value == 0) 0 else 1 // 1.0 == 1, 1.1 > 1
} else when (item.type) {
INT_ITEM -> {
val itemValue = (item as IntItem).value
if (value < itemValue) -1 else if (value == itemValue) 0 else 1
}
LONG_ITEM, BIGINTEGER_ITEM -> -1
STRING_ITEM -> 1 // 1.1 > 1-sp
LIST_ITEM -> 1 // 1.1 > 1-1
else -> throw IllegalStateException("invalid item: " + item.javaClass)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || javaClass != other.javaClass) {
return false
}
val intItem = other as IntItem
return value == intItem.value
}
override fun hashCode(): Int {
return value
}
override fun toString(): String {
return value.toString()
}
companion object {
val ZERO = IntItem()
}
}
/**
* Represents a numeric item in the version item list that can be represented with a long.
*/
private class LongItem internal constructor(str: String) :
Item {
private val value = str.toLong()
override val type: Int
get() = LONG_ITEM
override val isNull: Boolean
get() = value == 0L
override fun compareTo(item: Item?): Int {
return if (item == null) {
if (value == 0L) 0 else 1 // 1.0 == 1, 1.1 > 1
} else when (item.type) {
INT_ITEM -> 1
LONG_ITEM -> {
val itemValue = (item as LongItem).value
if (value < itemValue) -1 else if (value == itemValue) 0 else 1
}
BIGINTEGER_ITEM -> -1
STRING_ITEM -> 1 // 1.1 > 1-sp
LIST_ITEM -> 1 // 1.1 > 1-1
else -> throw IllegalStateException("invalid item: " + item.javaClass)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || javaClass != other.javaClass) {
return false
}
val longItem = other as LongItem
return value == longItem.value
}
override fun hashCode(): Int {
return (value xor (value ushr 32)).toInt()
}
override fun toString(): String {
return value.toString()
}
}
/**
* Represents a numeric item in the version item list.
*/
private class BigIntegerItem internal constructor(str: String?) :
Item {
private val value = BigInteger(str)
override val type: Int
get() = BIGINTEGER_ITEM
override val isNull: Boolean
get() = BigInteger.ZERO == value
override fun compareTo(item: Item?): Int {
return if (item == null) {
if (BigInteger.ZERO == value) 0 else 1 // 1.0 == 1, 1.1 > 1
} else when (item.type) {
INT_ITEM, LONG_ITEM -> 1
BIGINTEGER_ITEM -> value.compareTo((item as BigIntegerItem).value)
STRING_ITEM -> 1 // 1.1 > 1-sp
LIST_ITEM -> 1 // 1.1 > 1-1
else -> throw IllegalStateException("invalid item: " + item.javaClass)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || javaClass != other.javaClass) {
return false
}
val that = other as BigIntegerItem
return value == that.value
}
override fun hashCode(): Int {
return value.hashCode()
}
override fun toString(): String {
return value.toString()
}
}
/**
* Represents a string in the version item list, usually a qualifier.
*/
private class StringItem internal constructor(value: String, followedByDigit: Boolean) :
Item {
companion object {
private val QUALIFIERS = listOf("alpha", "beta", "milestone", "rc", "snapshot", "", "sp")
private val ALIASES = Properties()
/**
* A comparable value for the empty-string qualifier. This one is used to determine if a given qualifier makes
* the version older than one without a qualifier, or more recent.
*/
private val RELEASE_VERSION_INDEX = QUALIFIERS.indexOf("").toString()
/**
* Returns a comparable value for a qualifier.
*
*
* This method takes into account the ordering of known qualifiers then unknown qualifiers with lexical
* ordering.
*
*
* just returning an Integer with the index here is faster, but requires a lot of if/then/else to check for -1
* or QUALIFIERS.size and then resort to lexical ordering. Most comparisons are decided by the first character,
* so this is still fast. If more characters are needed then it requires a lexical sort anyway.
*
* @param qualifier
* @return an equivalent value that can be used with lexical comparison
*/
fun comparableQualifier(qualifier: String): String {
val i = QUALIFIERS.indexOf(qualifier)
return if (i == -1) QUALIFIERS.size.toString() + "-" + qualifier else i.toString()
}
init {
ALIASES["ga"] = ""
ALIASES["final"] = ""
ALIASES["release"] = ""
ALIASES["cr"] = "rc"
}
}
private val value: String
override val type: Int
get() = STRING_ITEM
override val isNull: Boolean
get() = comparableQualifier(
value
).compareTo(RELEASE_VERSION_INDEX) == 0
override fun compareTo(item: Item?): Int {
return if (item == null) {
// 1-rc < 1, 1-ga > 1
comparableQualifier(
value
)
.compareTo(RELEASE_VERSION_INDEX)
} else when (item.type) {
INT_ITEM, LONG_ITEM, BIGINTEGER_ITEM -> -1 // 1.any < 1.1 ?
STRING_ITEM -> comparableQualifier(
value
).compareTo(
comparableQualifier(
(item as StringItem).value
)
)
LIST_ITEM -> -1 // 1.any < 1-1
else -> throw IllegalStateException("invalid item: " + item.javaClass)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || javaClass != other.javaClass) {
return false
}
val that = other as StringItem
return value == that.value
}
override fun hashCode(): Int {
return value.hashCode()
}
override fun toString(): String {
return value
}
init {
var value = value
if (followedByDigit && value.length == 1) {
// a1 = alpha-1, b1 = beta-1, m1 = milestone-1
when (value[0]) {
'a' -> value = "alpha"
'b' -> value = "beta"
'm' -> value = "milestone"
else -> {
}
}
}
this.value = ALIASES.getProperty(value, value)
}
}
/**
* Represents a version list item. This class is used both for the global item list and for sub-lists (which start
* with '-(number)' in the version specification).
*/
private class ListItem : ArrayList<Item?>(),
Item {
override val type: Int
get() = LIST_ITEM
override val isNull: Boolean
get() = size == 0
internal fun normalize() {
for (i in size - 1 downTo 0) {
val lastItem = get(i)
if (lastItem!!.isNull) {
// remove null trailing items: 0, "", empty list
removeAt(i)
} else if (lastItem !is ListItem) {
break
}
}
}
override fun compareTo(item: Item?): Int {
if (item == null) {
if (size == 0) {
return 0 // 1-0 = 1- (normalize) = 1
}
val first = get(0)
return first!!.compareTo(null)
}
when (item.type) {
INT_ITEM, LONG_ITEM, BIGINTEGER_ITEM -> return -1 // 1-1 < 1.0.x
STRING_ITEM -> return 1 // 1-1 > 1-sp
LIST_ITEM -> {
val left: Iterator<Item?> = iterator()
val right: Iterator<Item?> = (item as ListItem).iterator()
while (left.hasNext() || right.hasNext()) {
val l = if (left.hasNext()) left.next() else null
val r = if (right.hasNext()) right.next() else null
// if this is shorter, then invert the compare and mul with -1
val result = l?.compareTo(r) ?: if (r == null) 0 else -1 * r.compareTo(l)
if (result != 0) {
return result
}
}
return 0
}
else -> throw IllegalStateException("invalid item: " + item.javaClass)
}
}
override fun toString(): String {
val buffer = StringBuilder()
for (item in this) {
if (buffer.length > 0) {
buffer.append(if (item is ListItem) '-' else '.')
}
buffer.append(item)
}
return buffer.toString()
}
}
private fun parseVersion(version: String) {
var version = version
value = version
items = ListItem()
version = version.toLowerCase(Locale.ENGLISH)
var list = items!!
val stack: Deque<Item> = ArrayDeque()
stack.push(list)
var isDigit = false
var startIndex = 0
for (i in version.indices) {
val c = version[i]
when {
c == '.' -> {
if (i == startIndex) {
list.add(IntItem.ZERO)
} else {
list.add(
parseItem(
isDigit,
version.substring(startIndex, i)
)
)
}
startIndex = i + 1
}
c == '-' -> {
if (i == startIndex) {
list.add(IntItem.ZERO)
} else {
list.add(
parseItem(
isDigit,
version.substring(startIndex, i)
)
)
}
startIndex = i + 1
list.add(ListItem().also { list = it })
stack.push(list)
}
Character.isDigit(c) -> {
if (!isDigit && i > startIndex) {
list.add(
StringItem(
version.substring(startIndex, i),
true
)
)
startIndex = i
list.add(ListItem().also { list = it })
stack.push(list)
}
isDigit = true
}
else -> {
if (isDigit && i > startIndex) {
list.add(
parseItem(
true,
version.substring(startIndex, i)
)
)
startIndex = i
list.add(ListItem().also { list = it })
stack.push(list)
}
isDigit = false
}
}
}
if (version.length > startIndex) {
list.add(
parseItem(
isDigit,
version.substring(startIndex)
)
)
}
while (!stack.isEmpty()) {
list = stack.pop() as ListItem
list.normalize()
}
}
override operator fun compareTo(other: ComparableVersion?): Int {
return items!!.compareTo(other?.items)
}
override fun toString(): String {
return value!!
}
override fun equals(other: Any?): Boolean {
return other is ComparableVersion && items == other.items
}
override fun hashCode(): Int {
return items.hashCode()
}
// CHECKSTYLE_OFF: LineLength
companion object {
private const val MAX_INTITEM_LENGTH = 9
private const val MAX_LONGITEM_LENGTH = 18
private fun parseItem(isDigit: Boolean, buf: String): Item {
var buf = buf
if (isDigit) {
buf =
stripLeadingZeroes(
buf
)
if (buf.length <= MAX_INTITEM_LENGTH) {
// lower than 2^31
return IntItem(buf)
} else if (buf.length <= MAX_LONGITEM_LENGTH) {
// lower than 2^63
return LongItem(
buf
)
}
return BigIntegerItem(
buf
)
}
return StringItem(
buf,
false
)
}
private fun stripLeadingZeroes(buf: String?): String {
if (buf == null || buf.isEmpty()) {
return "0"
}
for (i in buf.indices) {
val c = buf[i]
if (c != '0') {
return buf.substring(i)
}
}
return buf
}
}
init {
parseVersion(version)
}
}
@@ -1,180 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* http://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 org.jetbrains.kotlin.tools.projectWizard.settings.version.maven
import java.util.*
/**
* Default implementation of artifact versioning.
*
* @author [Brett Porter](mailto:brett@apache.org)
*/
class DefaultArtifactVersion(version: String) : ArtifactVersion {
private var _majorVersion: Int? = null
private var _minorVersion: Int? = null
private var _incrementalVersion: Int? = null
private var _buildNumber: Int? = null
override val majorVersion: Int
get() = _majorVersion ?: 0
override val minorVersion: Int
get() = _minorVersion ?: 0
override val incrementalVersion: Int
get() = _incrementalVersion ?: 0
override val buildNumber: Int
get() = _buildNumber ?: 0
override var qualifier: String? = null
private set
private var comparable: ComparableVersion? = null
override fun hashCode(): Int {
return 11 + comparable.hashCode()
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
return if (other !is ArtifactVersion) {
false
} else compareTo(other) == 0
}
override fun compareTo(other: ArtifactVersion?): Int {
return if (other is DefaultArtifactVersion) {
comparable!!.compareTo(other.comparable)
} else {
compareTo(DefaultArtifactVersion(other.toString()))
}
}
override fun parseVersion(version: String) {
comparable = ComparableVersion(version)
val index = version.indexOf('-')
val part1: String
var part2: String? = null
if (index < 0) {
part1 = version
} else {
part1 = version.substring(0, index)
part2 = version.substring(index + 1)
}
if (part2 != null) {
if (part2.length == 1 || !part2.startsWith("0")) {
_buildNumber = tryParseInt(part2)
if (_buildNumber == null) {
qualifier = part2
}
} else {
qualifier = part2
}
}
if (!part1.contains(".") && !part1.startsWith("0")) {
_majorVersion = tryParseInt(part1)
if (_majorVersion == null) {
// qualifier is the whole version, including "-"
qualifier = version
_buildNumber = null
}
} else {
var fallback = false
val tok = StringTokenizer(part1, ".")
if (tok.hasMoreTokens()) {
_majorVersion = getNextIntegerToken(tok)
if (_majorVersion == null) {
fallback = true
}
} else {
fallback = true
}
if (tok.hasMoreTokens()) {
_minorVersion = getNextIntegerToken(tok)
if (_minorVersion == null) {
fallback = true
}
}
if (tok.hasMoreTokens()) {
_incrementalVersion = getNextIntegerToken(tok)
if (_incrementalVersion == null) {
fallback = true
}
}
if (tok.hasMoreTokens()) {
qualifier = tok.nextToken()
fallback = isDigits(qualifier)
}
// string tokenizer won't detect these and ignores them
if (part1.contains("..") || part1.startsWith(".") || part1.endsWith(".")) {
fallback = true
}
if (fallback) {
// qualifier is the whole version, including "-"
qualifier = version
_majorVersion = null
_minorVersion = null
_incrementalVersion = null
_buildNumber = null
}
}
}
override fun toString(): String {
return comparable.toString()
}
companion object {
private fun getNextIntegerToken(tok: StringTokenizer): Int? {
val s = tok.nextToken()
return if (s.length > 1 && s.startsWith("0")) {
null
} else tryParseInt(s)
}
private fun tryParseInt(s: String): Int? {
// for performance, check digits instead of relying later on catching NumberFormatException
return if (!isDigits(s)) {
null
} else try {
val longValue = s.toLong()
if (longValue > Integer.MAX_VALUE) {
null
} else longValue.toInt()
} catch (e: NumberFormatException) {
// should never happen since checked isDigits(s) before
null
}
}
fun isDigits(string: String?) = string?.all { it.isDigit() } ?: false
}
init {
parseVersion(version)
}
}
@@ -1,109 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* http://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 org.jetbrains.kotlin.tools.projectWizard.settings.version.maven
/**
* Describes a restriction in versioning.
*
* @author [Brett Porter](mailto:brett@apache.org)
*/
class Restriction(
val lowerBound: ArtifactVersion?,
val isLowerBoundInclusive: Boolean,
val upperBound: ArtifactVersion?,
val isUpperBoundInclusive: Boolean
) {
fun containsVersion(version: ArtifactVersion): Boolean {
if (lowerBound != null) {
val comparison = lowerBound.compareTo(version)
if (comparison == 0 && !isLowerBoundInclusive) {
return false
}
if (comparison > 0) {
return false
}
}
if (upperBound != null) {
val comparison = upperBound.compareTo(version)
if (comparison == 0 && !isUpperBoundInclusive) {
return false
}
if (comparison < 0) {
return false
}
}
return true
}
override fun hashCode(): Int {
var result = 13
result += lowerBound?.hashCode() ?: 1
result *= if (isLowerBoundInclusive) 1 else 2
result -= upperBound?.hashCode() ?: 3
result *= if (isUpperBoundInclusive) 2 else 3
return result
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other !is Restriction) {
return false
}
if (lowerBound != null) {
if (lowerBound != other.lowerBound) {
return false
}
} else if (other.lowerBound != null) {
return false
}
if (isLowerBoundInclusive != other.isLowerBoundInclusive) {
return false
}
if (upperBound != null) {
if (upperBound != other.upperBound) {
return false
}
} else if (other.upperBound != null) {
return false
}
return isUpperBoundInclusive == other.isUpperBoundInclusive
}
override fun toString(): String {
val buf = StringBuilder()
buf.append(if (isLowerBoundInclusive) '[' else '(')
if (lowerBound != null) {
buf.append(lowerBound.toString())
}
buf.append(',')
if (upperBound != null) {
buf.append(upperBound.toString())
}
buf.append(if (isUpperBoundInclusive) ']' else ')')
return buf.toString()
}
companion object {
val EVERYTHING = Restriction(null, false, null, false)
}
}