diff --git a/.idea/libraries/de_cketti_unicode_kotlin_codepoints_jvm.xml b/.idea/libraries/de_cketti_unicode_kotlin_codepoints_jvm.xml
deleted file mode 100644
index 3a34960f459a..000000000000
--- a/.idea/libraries/de_cketti_unicode_kotlin_codepoints_jvm.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
- d642f145f6123739e779d4156145cc5fe7c2173bb58d437b813961a31c337ff9
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/fleet/util/codepoints/BUILD.bazel b/fleet/util/codepoints/BUILD.bazel
index 1db677424145..3c8b31714b26 100644
--- a/fleet/util/codepoints/BUILD.bazel
+++ b/fleet/util/codepoints/BUILD.bazel
@@ -1,6 +1,6 @@
### auto-generated section `build fleet.util.codepoints` start
load("//build:compiler-options.bzl", "create_kotlinc_options")
-load("@rules_jvm//:jvm.bzl", "jvm_library", "resourcegroup")
+load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_provided_library", "resourcegroup")
create_kotlinc_options(
name = "custom_codepoints",
@@ -15,17 +15,22 @@ resourcegroup(
strip_prefix = "resources"
)
+jvm_provided_library(
+ name = "fleet_util_multiplatform_provided",
+ lib = "//fleet/util/multiplatform"
+)
+
jvm_library(
name = "codepoints",
module_name = "fleet.util.codepoints",
visibility = ["//visibility:public"],
- srcs = glob(["srcCommonMain/**/*.kt", "srcCommonMain/**/*.java", "srcCommonMain/**/*.form"], allow_empty = True, exclude = ["**/module-info.java"]),
+ srcs = glob(["srcCommonMain/**/*.kt", "srcCommonMain/**/*.java", "srcCommonMain/**/*.form", "srcJvmMain/**/*.kt", "srcJvmMain/**/*.java", "srcJvmMain/**/*.form"], allow_empty = True, exclude = ["**/module-info.java"]),
resources = [":codepoints_resources"],
kotlinc_opts = ":custom_codepoints",
deps = [
"@lib//:kotlin-stdlib",
"//fleet/util/core",
- "@lib//:de-cketti-unicode-kotlin-codepoints-jvm",
+ ":fleet_util_multiplatform_provided",
]
)
### auto-generated section `build fleet.util.codepoints` end
\ No newline at end of file
diff --git a/fleet/util/codepoints/fleet.util.codepoints.iml b/fleet/util/codepoints/fleet.util.codepoints.iml
index d520303e21f6..98da95895082 100644
--- a/fleet/util/codepoints/fleet.util.codepoints.iml
+++ b/fleet/util/codepoints/fleet.util.codepoints.iml
@@ -12,6 +12,11 @@
+
+
+ $MAVEN_REPOSITORY$/jetbrains/fleet/expects-compiler-plugin/2.2.21-RC2-0.1/expects-compiler-plugin-2.2.21-RC2-0.1.jar
+
+
@@ -21,11 +26,12 @@
+
-
+
\ No newline at end of file
diff --git a/fleet/util/codepoints/gradlebuild/build.gradle.kts b/fleet/util/codepoints/gradlebuild/build.gradle.kts
index 9b3540e29ec2..76d661da9335 100644
--- a/fleet/util/codepoints/gradlebuild/build.gradle.kts
+++ b/fleet/util/codepoints/gradlebuild/build.gradle.kts
@@ -12,6 +12,7 @@ plugins {
alias(libs.plugins.dokka)
// GRADLE_PLUGINS__MARKER_START
id("fleet-module")
+ alias(jps.plugins.expects)
// GRADLE_PLUGINS__MARKER_END
}
@@ -57,10 +58,13 @@ kotlin {
implementation(jps.org.jetbrains.kotlin.kotlin.stdlib1993400674.get().let { "${it.group}:${it.name}:${it.version}" }) {
exclude(group = "org.jetbrains", module = "annotations")
}
- implementation(jps.de.cketti.unicode.kotlin.codepoints.jvm1960123061.get().let { "${it.group}:kotlin-codepoints:${it.version}" }) {
- isTransitive = false
- }
implementation(project(":fleet.util.core"))
}
+ sourceSets.jvmMain.dependencies {
+ compileOnly(project(":fleet.util.multiplatform"))
+ }
+ sourceSets.wasmJsMain.dependencies {
+ implementation(project(":fleet.util.multiplatform"))
+ }
// KOTLIN__MARKER_END
}
\ No newline at end of file
diff --git a/fleet/util/codepoints/module-content.yaml b/fleet/util/codepoints/module-content.yaml
index d87532ab08ab..29fa9f6b6d49 100644
--- a/fleet/util/codepoints/module-content.yaml
+++ b/fleet/util/codepoints/module-content.yaml
@@ -1,6 +1,3 @@
- name: dist.all/lib/fleet.util.codepoints.jar
modules:
- - name: fleet.util.codepoints
- library: de.cketti.unicode.kotlin.codepoints.jvm
- files:
- - name: $MAVEN_REPOSITORY$/de/cketti/unicode/kotlin-codepoints-jvm/0/kotlin-codepoints-jvm-0.jar
\ No newline at end of file
+ - name: fleet.util.codepoints
\ No newline at end of file
diff --git a/fleet/util/codepoints/srcCommonMain/fleet/codepoints/AppendableExtensions.kt b/fleet/util/codepoints/srcCommonMain/fleet/codepoints/AppendableExtensions.kt
new file mode 100644
index 000000000000..4d3a22ae3d94
--- /dev/null
+++ b/fleet/util/codepoints/srcCommonMain/fleet/codepoints/AppendableExtensions.kt
@@ -0,0 +1,12 @@
+package fleet.codepoints
+
+fun T.appendCodePoint(codepoint: Codepoint): T {
+ if (codepoint.isBmpCodePoint()) {
+ append(codepoint.codepoint.toChar())
+ }
+ else {
+ append(highSurrogatePlatformSpecific(codepoint.codepoint))
+ append(lowSurrogatePlatformSpecific(codepoint.codepoint))
+ }
+ return this
+}
diff --git a/fleet/util/codepoints/srcCommonMain/fleet/codepoints/CharSequenceExtensions.kt b/fleet/util/codepoints/srcCommonMain/fleet/codepoints/CharSequenceExtensions.kt
new file mode 100644
index 000000000000..baaf02adcef6
--- /dev/null
+++ b/fleet/util/codepoints/srcCommonMain/fleet/codepoints/CharSequenceExtensions.kt
@@ -0,0 +1,73 @@
+package fleet.codepoints
+
+fun CharSequence.codePointAt(index: Int): Codepoint {
+ if (index !in indices) throw IndexOutOfBoundsException("Index out of range: $index, size: $length")
+
+ val firstChar = this[index]
+ if (firstChar.isHighSurrogate() && index + 1 < length) {
+ val secondChar = this[index + 1]
+ if (secondChar.isLowSurrogate()) {
+ return Codepoint.fromChars(firstChar, secondChar)
+ }
+ }
+ return Codepoint(firstChar.code)
+}
+
+fun CharSequence.codePointBefore(index: Int): Codepoint {
+ val startIndex = index - 1
+ if (startIndex < 0 || index !in indices) throw IndexOutOfBoundsException("Index out of range: $index, size: $length")
+
+ val secondChar = this[startIndex]
+ if (secondChar.isLowSurrogate() && startIndex - 1 >= 0) {
+ val firstChar = this[startIndex - 1]
+ if (firstChar.isHighSurrogate()) {
+ return Codepoint.fromChars(firstChar, secondChar)
+ }
+ }
+
+ return Codepoint(secondChar.code)
+}
+
+fun CharSequence.codepoints(offset: Int, direction: Direction = Direction.FORWARD): Iterator =
+ when (direction) {
+ Direction.FORWARD -> iterator {
+ var i = offset
+ val len = length
+ while (i < len) {
+ val c1 = get(i++)
+ if (c1.isHighSurrogate()) {
+ if (i < len) {
+ val c2 = get(i++)
+ if (c2.isLowSurrogate()) {
+ yield(Codepoint.fromChars(c1, c2))
+ }
+ }
+ }
+ else {
+ yield(Codepoint(c1.code))
+ }
+ }
+ }
+ Direction.BACKWARD -> iterator {
+ var i = offset - 1
+ while (i >= 0) {
+ val c2 = get(i--)
+ if (c2.isLowSurrogate()) {
+ if (i >= 0) {
+ val c1 = get(i--)
+ if (c1.isHighSurrogate()) {
+ yield(Codepoint.fromChars(c1, c2))
+ }
+ }
+ }
+ else {
+ yield(Codepoint(c2.code))
+ }
+ }
+ }
+ }
+
+enum class Direction {
+ FORWARD,
+ BACKWARD,
+}
\ No newline at end of file
diff --git a/fleet/util/codepoints/srcCommonMain/fleet/codepoints/Codepoint.kt b/fleet/util/codepoints/srcCommonMain/fleet/codepoints/Codepoint.kt
index adeee5eb3878..2900e5de88a2 100644
--- a/fleet/util/codepoints/srcCommonMain/fleet/codepoints/Codepoint.kt
+++ b/fleet/util/codepoints/srcCommonMain/fleet/codepoints/Codepoint.kt
@@ -1,14 +1,19 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package fleet.codepoints
-import de.cketti.codepoints.CodePoints
import kotlin.jvm.JvmInline
@JvmInline
value class Codepoint(val codepoint: Int) {
- val charCount: Int get() = CodePoints.charCount(codepoint)
+ val charCount: Int
+ get() = if (codepoint < MIN_SUPPLEMENTARY_CODE_POINT) 1 else 2
+
+ fun asString(): String = toString(codepoint)
+
+ internal fun isBmpCodePoint(): Boolean = codepoint ushr 16 == 0
companion object {
+ fun fromChars(highSurrogate: Char, lowSurrogate: Char ): Codepoint = codepointOfPlatformSpecific(highSurrogate, lowSurrogate)
fun isUnicodeIdentifierStart(codepoint: Int): Boolean = isCodepointInRanges(codepoint, unicodeIdStartRanges)
fun isUnicodeIdentifierPart(codepoint: Int): Boolean = isCodepointInRanges(codepoint, unicodeIdContinueRanges)
fun isIdentifierIgnorable(codepoint: Int): Boolean = isCodepointInRanges(codepoint, identifierIgnorableRanges)
@@ -39,51 +44,7 @@ value class Codepoint(val codepoint: Int) {
}
fun toString(codepoint: Int): String {
- return CodePoints.toString(codepoint)
+ return codePointsToStringPlatformSpecific(codepoint)
}
}
}
-
-fun CharSequence.codepoints(offset: Int, direction: Direction = Direction.FORWARD): Iterator =
- when (direction) {
- Direction.FORWARD -> iterator {
- var i = offset
- val len = length
- while (i < len) {
- val c1 = get(i++)
- if (c1.isHighSurrogate()) {
- if (i < len) {
- val c2 = get(i++)
- if (c2.isLowSurrogate()) {
- yield(Codepoint(CodePoints.toCodePoint(c1, c2)))
- }
- }
- }
- else {
- yield(Codepoint(c1.code))
- }
- }
- }
- Direction.BACKWARD -> iterator {
- var i = offset - 1
- while (i >= 0) {
- val c2 = get(i--)
- if (c2.isLowSurrogate()) {
- if (i >= 0) {
- val c1 = get(i--)
- if (c1.isHighSurrogate()) {
- yield(Codepoint(CodePoints.toCodePoint(c1, c2)))
- }
- }
- }
- else {
- yield(Codepoint(c2.code))
- }
- }
- }
- }
-
-enum class Direction {
- FORWARD,
- BACKWARD,
-}
\ No newline at end of file
diff --git a/fleet/util/codepoints/srcCommonMain/fleet/codepoints/MultiplatformCodepoint.kt b/fleet/util/codepoints/srcCommonMain/fleet/codepoints/MultiplatformCodepoint.kt
new file mode 100644
index 000000000000..277abae26d83
--- /dev/null
+++ b/fleet/util/codepoints/srcCommonMain/fleet/codepoints/MultiplatformCodepoint.kt
@@ -0,0 +1,37 @@
+package fleet.codepoints
+
+import fleet.util.multiplatform.linkToActual
+
+internal const val MIN_SUPPLEMENTARY_CODE_POINT = 0x10000
+private const val MIN_HIGH_SURROGATE = 0xD800
+private const val MIN_LOW_SURROGATE = 0xDC00
+private const val SURROGATE_DECODE_OFFSET = MIN_SUPPLEMENTARY_CODE_POINT - (MIN_HIGH_SURROGATE shl 10) - MIN_LOW_SURROGATE
+private const val HIGH_SURROGATE_ENCODE_OFFSET = (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT ushr 10))
+
+internal fun codePointsToStringPlatformSpecific(vararg codepoints: Int): String = linkToActual()
+
+internal fun codePointsToStringMultiplatform(vararg codepoints: Int): String {
+ return buildString(capacity = codepoints.size * 2) {
+ for (codePoint in codepoints) {
+ appendCodePoint(Codepoint(codePoint))
+ }
+ }
+}
+
+internal fun codepointOfPlatformSpecific(highSurrogate: Char, lowSurrogate: Char): Codepoint = linkToActual()
+
+internal fun codepointOfMultiplatform(highSurrogate: Char, lowSurrogate: Char): Codepoint {
+ return Codepoint((highSurrogate.code shl 10) + lowSurrogate.code + SURROGATE_DECODE_OFFSET)
+}
+
+internal fun highSurrogatePlatformSpecific(codepoint: Int): Char = linkToActual()
+
+internal fun highSurrogateMultiplatform(codepoint: Int): Char {
+ return ((codepoint ushr 10) + HIGH_SURROGATE_ENCODE_OFFSET).toChar()
+}
+
+internal fun lowSurrogatePlatformSpecific(codepoint: Int): Char = linkToActual()
+
+internal fun lowSurrogateMultiplatform(codepoint: Int): Char {
+ return ((codepoint and 0x3FF) + MIN_LOW_SURROGATE).toChar()
+}
\ No newline at end of file
diff --git a/fleet/util/codepoints/srcJvmMain/fleet/codepoints/MultiplatformCodepoint.jvm.kt b/fleet/util/codepoints/srcJvmMain/fleet/codepoints/MultiplatformCodepoint.jvm.kt
new file mode 100644
index 000000000000..aefce7846c5a
--- /dev/null
+++ b/fleet/util/codepoints/srcJvmMain/fleet/codepoints/MultiplatformCodepoint.jvm.kt
@@ -0,0 +1,19 @@
+package fleet.codepoints
+
+import fleet.util.multiplatform.Actual
+
+@Actual
+internal fun codePointsToStringPlatformSpecificJvm(vararg codepoints: Int): String {
+ return String(codepoints, 0, codepoints.size)
+}
+
+@Actual
+internal fun codepointOfPlatformSpecificJvm(highSurrogate: Char, lowSurrogate: Char): Codepoint {
+ return Codepoint(Character.toCodePoint(highSurrogate, lowSurrogate))
+}
+
+@Actual
+internal fun highSurrogatePlatformSpecificJvm(codepoint: Int): Char = Character.highSurrogate(codepoint)
+
+@Actual
+internal fun lowSurrogatePlatformSpecificJvm(codepoint: Int): Char = Character.lowSurrogate(codepoint)
\ No newline at end of file
diff --git a/fleet/util/codepoints/srcNativeMain/fleet/codepoints/MultiplatformCodepoint.native.kt b/fleet/util/codepoints/srcNativeMain/fleet/codepoints/MultiplatformCodepoint.native.kt
new file mode 100644
index 000000000000..84f8eb6804ee
--- /dev/null
+++ b/fleet/util/codepoints/srcNativeMain/fleet/codepoints/MultiplatformCodepoint.native.kt
@@ -0,0 +1,17 @@
+package fleet.codepoints
+
+@fleet.util.multiplatform.Actual
+internal fun codePointsToStringPlatformSpecificNative(vararg codepoints: Int): String {
+ return codePointsToStringMultiplatform(*codepoints)
+}
+
+@fleet.util.multiplatform.Actual
+internal fun codepointOfPlatformSpecificNative(highSurrogate: Char, lowSurrogate: Char): Codepoint {
+ return codepointOfMultiplatform(highSurrogate, lowSurrogate)
+}
+
+@fleet.util.multiplatform.Actual
+internal fun highSurrogatePlatformSpecificNative(codepoint: Int): Char = highSurrogateMultiplatform(codepoint)
+
+@fleet.util.multiplatform.Actual
+internal fun lowSurrogatePlatformSpecificNative(codepoint: Int): Char = lowSurrogateMultiplatform(codepoint
\ No newline at end of file
diff --git a/fleet/util/codepoints/srcWasmJsMain/fleet/codepoints/MultiplatformCodepoint.wasm.kt b/fleet/util/codepoints/srcWasmJsMain/fleet/codepoints/MultiplatformCodepoint.wasm.kt
new file mode 100644
index 000000000000..b5bad79592f1
--- /dev/null
+++ b/fleet/util/codepoints/srcWasmJsMain/fleet/codepoints/MultiplatformCodepoint.wasm.kt
@@ -0,0 +1,17 @@
+package fleet.codepoints
+
+@fleet.util.multiplatform.Actual
+internal fun codePointsToStringPlatformSpecificWasmJs(vararg codepoints: Int): String {
+ return codePointsToStringMultiplatform(*codepoints)
+}
+
+@fleet.util.multiplatform.Actual
+internal fun codepointOfPlatformSpecificWasmJs(highSurrogate: Char, lowSurrogate: Char): Codepoint {
+ return codepointOfMultiplatform(highSurrogate, lowSurrogate)
+}
+
+@fleet.util.multiplatform.Actual
+internal fun highSurrogatePlatformSpecificWasmJs(codepoint: Int): Char = highSurrogateMultiplatform(codepoint)
+
+@fleet.util.multiplatform.Actual
+internal fun lowSurrogatePlatformSpecificWasmJs(codepoint: Int): Char = lowSurrogateMultiplatform(codepoint)
\ No newline at end of file
diff --git a/lib/BUILD.bazel b/lib/BUILD.bazel
index d1ff90c4408b..e5acd200c978 100644
--- a/lib/BUILD.bazel
+++ b/lib/BUILD.bazel
@@ -1074,13 +1074,6 @@ jvm_import(
visibility = ["//visibility:public"]
)
-jvm_import(
- name = "de-cketti-unicode-kotlin-codepoints-jvm",
- jar = "@de_cketti_unicode-kotlin-codepoints-jvm-0_9_0_http//file",
- source_jar = "@de_cketti_unicode-kotlin-codepoints-jvm-0_9_0-sources_http//file",
- visibility = ["//visibility:public"]
-)
-
jvm_import(
name = "download-pgp-verifier",
jar = "@com_jetbrains_infra-download-pgp-verifier-1_1_4_http//file",
diff --git a/lib/MODULE.bazel b/lib/MODULE.bazel
index ba54ea98f202..6c6628f1cd99 100644
--- a/lib/MODULE.bazel
+++ b/lib/MODULE.bazel
@@ -1322,20 +1322,6 @@ http_file(
downloaded_file_path = "cucumber-jvm-deps-1.0.5-sources.jar"
)
-http_file(
- name = "de_cketti_unicode-kotlin-codepoints-jvm-0_9_0_http",
- url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/de/cketti/unicode/kotlin-codepoints-jvm/0.9.0/kotlin-codepoints-jvm-0.9.0.jar",
- sha256 = "d642f145f6123739e779d4156145cc5fe7c2173bb58d437b813961a31c337ff9",
- downloaded_file_path = "kotlin-codepoints-jvm-0.9.0.jar"
-)
-
-http_file(
- name = "de_cketti_unicode-kotlin-codepoints-jvm-0_9_0-sources_http",
- url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/de/cketti/unicode/kotlin-codepoints-jvm/0.9.0/kotlin-codepoints-jvm-0.9.0-sources.jar",
- sha256 = "713ed1a4bf439eda3a304bce8a713380fc60221dbd34c49bcda0999f4cdf6937",
- downloaded_file_path = "kotlin-codepoints-jvm-0.9.0-sources.jar"
-)
-
http_file(
name = "com_jetbrains_infra-download-pgp-verifier-1_1_4_http",
url = "https://cache-redirector.jetbrains.com/packages.jetbrains.team/maven/p/ij/intellij-dependencies/com/jetbrains/infra/download-pgp-verifier/1.1.4/download-pgp-verifier-1.1.4.jar",
diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/CommunityLibraryLicenses.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/CommunityLibraryLicenses.kt
index 64abd198b3d1..b61d61e8a614 100644
--- a/platform/build-scripts/src/org/jetbrains/intellij/build/CommunityLibraryLicenses.kt
+++ b/platform/build-scripts/src/org/jetbrains/intellij/build/CommunityLibraryLicenses.kt
@@ -792,9 +792,6 @@ object CommunityLibraryLicenses {
.apache("https://github.com/JetBrains/kotlin/blob/master/license/LICENSE.txt")
.suppliedByOrganizations(Suppliers.JETBRAINS),
- LibraryLicense("kotlin-codepoints", libraryName = "de.cketti.unicode.kotlin.codepoints.jvm", url = "https://github.com/cketti/kotlin-codepoints")
- .mit("https://github.com/cketti/kotlin-codepoints/blob/main/LICENSE"),
-
LibraryLicense("kotlin-metadata", libraryName = "kotlin-metadata", url = "https://github.com/JetBrains/kotlin")
.apache("https://github.com/JetBrains/kotlin/blob/master/license/LICENSE.txt")
.suppliedByOrganizations(Suppliers.JETBRAINS),