diff --git a/.github/detekt.yml b/.github/detekt.yml
index 1d15fa7..b53d2ea 100644
--- a/.github/detekt.yml
+++ b/.github/detekt.yml
@@ -1,4 +1,7 @@
complexity:
+ CyclomaticComplexMethod:
+ ignoreFunction:
+ - "io.github.treesitter.ktreesitter.Query.Companion.init"
TooManyFunctions:
active: false
LongParameterList:
diff --git a/.github/scripts/build-jni.ps1 b/.github/scripts/build-jni.ps1
index cc33042..5539ddb 100755
--- a/.github/scripts/build-jni.ps1
+++ b/.github/scripts/build-jni.ps1
@@ -2,7 +2,7 @@
& cmake -S ktreesitter -B ktreesitter/.cmake/build `
-DCMAKE_VERBOSE_MAKEFILE=ON `
- -DCMAKE_INSTALL_PREFIX=ktreesitter/src/jvmMain/resources `
+ -DCMAKE_INSTALL_PREFIX=ktreesitter/src/jvmMain/resources `
-DCMAKE_INSTALL_BINDIR="$env:CMAKE_INSTALL_LIBDIR"
& cmake --build ktreesitter/.cmake/build --config Debug
& cmake --install ktreesitter/.cmake/build --config Debug
diff --git a/.github/scripts/build-jni.sh b/.github/scripts/build-jni.sh
index 89474b8..85df4b9 100755
--- a/.github/scripts/build-jni.sh
+++ b/.github/scripts/build-jni.sh
@@ -3,7 +3,7 @@
cmake -S ktreesitter -B ktreesitter/.cmake/build \
-DCMAKE_BUILD_TYPE=RelWithDebugInfo \
-DCMAKE_VERBOSE_MAKEFILE=ON \
- -DCMAKE_OSX_ARCHITECTURES=arm64 \
+ -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' \
-DCMAKE_INSTALL_PREFIX=ktreesitter/src/jvmMain/resources \
-DCMAKE_INSTALL_LIBDIR="$CMAKE_INSTALL_LIBDIR"
cmake --build ktreesitter/.cmake/build
@@ -12,7 +12,7 @@ cmake --install ktreesitter/.cmake/build
for dir in languages/*/; do
cmake -S "${dir}build/generated" -B "${dir}.cmake/build" \
-DCMAKE_BUILD_TYPE=RelWithDebugInfo \
- -DCMAKE_OSX_ARCHITECTURES=arm64 \
+ -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' \
-DCMAKE_INSTALL_PREFIX="${dir}build/generated/src/jvmMain/resources" \
-DCMAKE_INSTALL_LIBDIR="$CMAKE_INSTALL_LIBDIR"
cmake --build "${dir}.cmake/build"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 52bd8e9..a37448b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,6 +9,7 @@ on:
- "**/jni/*"
- gradle/**
- gradle.properties
+ - ktreesitter/gradle.lockfile
pull_request:
paths:
- "/*.kt"
@@ -16,6 +17,7 @@ on:
- "**/jni/*"
- gradle/**
- gradle.properties
+ - ktreesitter/gradle.lockfile
concurrency:
cancel-in-progress: true
@@ -42,15 +44,13 @@ jobs:
cache-dependency-path: |
gradle/libs.versions.toml
gradle/wrapper/gradle-wrapper.properties
- - name: Cache Kotlin/Native prebuilt
- uses: actions/cache@v4
+ ktreesitter/gradle.lockfile
+ - name: Set up Kotlin/Native
+ uses: ObserverOfTime/setup-konan-action@v1
with:
- path: ${{runner.tool_cache}}/konan/kotlin-native-prebuilt-*
- key: konan-${{runner.os}}-prebuilt-1.9
+ kotlin_version: 2.1.21
- name: Generate files
run: ./gradlew --no-daemon generateGrammarFiles
- env:
- KONAN_DATA_DIR: ${{runner.tool_cache}}/konan
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
@@ -113,14 +113,20 @@ jobs:
cache-dependency-path: |
gradle/libs.versions.toml
gradle/wrapper/gradle-wrapper.properties
+ - name: Set up Kotlin/Native
+ uses: ObserverOfTime/setup-konan-action@v1
+ with:
+ kotlin_version: 2.1.21
- name: Set up cross compilation
- run: sudo apt-get install -qy {binutils,gcc}-aarch64-linux-gnu
if: matrix.platform == 'Linux'
- - name: Restore Kotlin/Native prebuilt
- uses: actions/cache/restore@v4
- with:
- path: ${{runner.tool_cache}}/konan/kotlin-native-prebuilt-*
- key: konan-${{runner.os}}-prebuilt-1.9
+ run: |-
+ sudo apt-get update
+ sudo apt-get install -qy {binutils,gcc}-aarch64-linux-gnu
+ - name: Set up Ninja
+ if: matrix.platform == 'Android'
+ run: |-
+ sudo apt-get update
+ sudo apt-get install -qy ninja-build
- name: Download generated files
uses: actions/download-artifact@v4
with:
@@ -131,30 +137,8 @@ jobs:
run: .github/scripts/build-jni.${{matrix.os == 'windows-latest' && 'ps1' || 'sh'}}
env:
CMAKE_INSTALL_LIBDIR: lib/${{matrix.lib_platform}}/${{matrix.lib_arch}}
- - name: Cache Kotlin/Native dependencies
- id: cache-dependencies
- uses: actions/cache@v4
- if: matrix.platform != 'JVM' && matrix.platform != 'Android'
- with:
- path: ${{runner.tool_cache}}/konan/dependencies
- key: konan-${{runner.os}}-dependencies
- - name: Download Kotlin/Native dependencies
- if: matrix.platform == 'macOS/iOS' && steps.cache-dependencies.outputs.cache-hit != 'true'
- run: |-
- mkdir -p "$RUNNER_TOOL_CACHE/konan/dependencies"
- curl -LSs https://download-cdn.jetbrains.com/kotlin/native/$DEP.tar.gz | \
- tar -xzf - -C "$RUNNER_TOOL_CACHE/konan/dependencies"
- env:
- DEP: apple-llvm-20200714-macos-aarch64-essentials
- - name: Set up Ninja
- if: matrix.platform == 'Android'
- run: |-
- sudo apt-get update
- sudo apt-get install -y ninja-build
- name: Run tests
run: ./gradlew --no-daemon ${{matrix.targets}}
- env:
- KONAN_DATA_DIR: ${{runner.tool_cache}}/konan
- name: Report test results
uses: mikepenz/action-junit-report@v5
if: matrix.platform == 'JVM' && !cancelled()
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index f013fb7..953e350 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -44,24 +44,22 @@ jobs:
cache-dependency-path: |
gradle/libs.versions.toml
gradle/wrapper/gradle-wrapper.properties
- - name: Restore Kotlin/Native prebuilt
- uses: actions/cache/restore@v4
+ - name: Set up Kotlin/Native
+ uses: ObserverOfTime/setup-konan-action@v1
with:
- path: ${{runner.tool_cache}}/konan/kotlin-native-prebuilt-*
- key: konan-${{runner.os}}-prebuilt-1.9
- - name: Restore Kotlin/Native dependencies
- uses: actions/cache/restore@v4
- with:
- path: ${{runner.tool_cache}}/konan/dependencies
- key: konan-${{runner.os}}-dependencies
+ kotlin_version: 2.1.21
+ - name: Set up cross compilation
+ if: matrix.platform == 'Linux'
+ run: |-
+ sudo apt-get update
+ sudo apt-get install -qy {binutils,gcc}-aarch64-linux-gnu
- name: Set up Ninja
+ if: matrix.platform == 'Android'
run: |-
sudo apt-get update
- sudo apt-get install -y ninja-build
+ sudo apt-get install -qy ninja-build
- name: Build documentation
- run: ./gradlew --no-daemon generateFiles :ktreesitter:dokkaHtml
- env:
- KONAN_DATA_DIR: ${{runner.tool_cache}}/konan
+ run: ./gradlew --no-daemon generateFiles :ktreesitter:dokkaGeneratePublicationHtml
- name: Upload pages artifact
uses: actions/upload-pages-artifact@v3
with:
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 36aea66..c182474 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -34,7 +34,7 @@ jobs:
java-version: 17
- name: Install ktlint
run: |-
- curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.3.1/ktlint
+ curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.6.0/ktlint
chmod a+x ktlint && mv ktlint $RUNNER_TOOL_CACHE/ktlint
- name: Run ktlint
id: ktlint
@@ -59,8 +59,8 @@ jobs:
java-version: 17
- name: Install detekt
run: |-
- curl -sSLO https://github.com/detekt/detekt/releases/download/v1.23.7/detekt-cli-1.23.7-all.jar
- mv detekt-cli-1.23.7-all.jar $RUNNER_TOOL_CACHE/detekt-cli.jar
+ curl -sSLO https://github.com/detekt/detekt/releases/download/v1.23.8/detekt-cli-1.23.8-all.jar
+ mv detekt-cli-1.23.8-all.jar $RUNNER_TOOL_CACHE/detekt-cli.jar
- name: Run detekt
id: detekt
run: >-
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 4b4e134..6e89bf6 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -132,20 +132,20 @@ jobs:
cache-dependency-path: |
gradle/libs.versions.toml
gradle/wrapper/gradle-wrapper.properties
- - name: Set up cross compilation
- run: sudo apt-get install -qy {binutils,gcc}-aarch64-linux-gnu
- if: matrix.platform == 'Linux' || matrix.platform == 'common'
- - name: Restore Kotlin/Native prebuilt
- uses: actions/cache/restore@v4
+ - name: Set up Kotlin/Native
+ uses: ObserverOfTime/setup-konan-action@v1
with:
- path: ${{runner.tool_cache}}/konan/kotlin-native-prebuilt-*
- key: konan-${{runner.os}}-prebuilt-1.9
- - name: Restore Kotlin/Native dependencies
- uses: actions/cache/restore@v4
- if: matrix.platform != 'JVM' && matrix.platform != 'Android'
- with:
- path: ${{runner.tool_cache}}/konan/dependencies
- key: konan-${{runner.os}}-dependencies
+ kotlin_version: 2.1.21
+ - name: Set up cross compilation
+ if: matrix.platform == 'Linux'
+ run: |-
+ sudo apt-get update
+ sudo apt-get install -qy {binutils,gcc}-aarch64-linux-gnu
+ - name: Set up Ninja
+ if: matrix.platform == 'Android'
+ run: |-
+ sudo apt-get update
+ sudo apt-get install -qy ninja-build
- name: Download library artifacts
uses: actions/download-artifact@v4
if: matrix.platform == 'JVM'
@@ -153,17 +153,11 @@ jobs:
path: ktreesitter/src/jvmMain/resources/lib
pattern: ktreesitter-lib-*
merge-multiple: true
- - name: Set up Ninja
- if: matrix.platform == 'Android'
- run: |-
- sudo apt-get update
- sudo apt-get install -y ninja-build
- name: Build packages
run: ./gradlew --no-daemon ${{matrix.targets}}
env:
SIGNING_KEY: ${{secrets.SIGNING_KEY}}
SIGNING_PASSWORD: ${{secrets.SIGNING_PASSWORD}}
- KONAN_DATA_DIR: ${{runner.tool_cache}}/konan
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
@@ -235,14 +229,12 @@ jobs:
cache-dependency-path: |
gradle/libs.versions.toml
gradle/wrapper/gradle-wrapper.properties
- - name: Restore Kotlin/Native prebuilt
- uses: actions/cache/restore@v4
+ - name: Set up Kotlin/Native
+ uses: ObserverOfTime/setup-konan-action@v1
with:
- path: ${{runner.tool_cache}}/konan/kotlin-native-prebuilt-*
- key: konan-${{runner.os}}-prebuilt-1.9
+ kotlin_version: 2.1.21
- name: Publish Gradle plugin
run: ./gradlew --no-daemon :ktreesitter-plugin:publishPlugins
env:
- KONAN_DATA_DIR: ${{runner.tool_cache}}/konan
GRADLE_PUBLISH_KEY: ${{secrets.GRADLE_PUBLISH_KEY}}
GRADLE_PUBLISH_SECRET: ${{secrets.GRADLE_PUBLISH_SECRET}}
diff --git a/.gitignore b/.gitignore
index cff9142..74ee895 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
### Gradle ###
.gradle/
build/
+.kotlin/
kotlin-js-store/
dependency-graph-reports/
local.properties
diff --git a/.gitmodules b/.gitmodules
index c059394..581ed41 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,7 +1,7 @@
[submodule "tree-sitter"]
path = tree-sitter
url = https://github.com/tree-sitter/tree-sitter
- branch = release-0.24
+ branch = release-0.25
[submodule "tree-sitter-java"]
path = languages/java/tree-sitter-java
diff --git a/.idea/ktlint-plugin.xml b/.idea/ktlint-plugin.xml
index bee5678..e68ca2d 100644
--- a/.idea/ktlint-plugin.xml
+++ b/.idea/ktlint-plugin.xml
@@ -1,6 +1,7 @@
-
+
DISTRACT_FREE
+ DEFAULT
-
\ No newline at end of file
+
diff --git a/build.gradle.kts b/build.gradle.kts
index ef9790e..7f3634f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -17,6 +17,6 @@ subprojects {
}
tasks.wrapper {
- gradleVersion = "8.7"
+ gradleVersion = "8.11"
distributionType = Wrapper.DistributionType.BIN
}
diff --git a/gradle.properties b/gradle.properties
index 2198304..863a326 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,13 +2,13 @@
project.version=0.24.1
# The Android SDK version that is used to compile the project.
-sdk.version.compile=34
+sdk.version.compile=35
# The minimum supported Android SDK version.
sdk.version.min=23
# The Android NDK version that is used to compile the project.
-ndk.version=26.3.11579264
+ndk.version=27.2.12479018
# The CMake version that is used to compile the project.
-cmake.version=3.31.3
+cmake.version=3.31.6
# Specifies the JVM arguments used for the daemon process.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
@@ -23,6 +23,8 @@ kotlin.code.style=official
kotlin.mpp.androidSourceSetLayoutVersion=2
# Enable C interop sharing
kotlin.mpp.enableCInteropCommonization=true
+# Enable cross-compilation of klib artifacts
+kotlin.native.enableKlibsCrossCompilation=true
# Disable default stdlib dependency
kotlin.stdlib.default.dependency=false
# Ignore disabled Kotlin/Native targets
@@ -32,3 +34,7 @@ kotlin.native.ignoreDisabledTargets=true
android.useAndroidX=true
# Disables automatically downloading the Android SDK.
android.builder.sdkDownload=false
+
+# Enables the experimental Dokka V2 mode.
+org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
+org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index b6b9ff1..0c600e8 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,61 +1,24 @@
[versions]
-kotlin-stdlib = "[1.9,2.0)"
-#noinspection GradleDependency
-android-gradle = {strictly = "8.2.0"}
-kotest = "5.9.1"
-dokka = "1.9.20"
-
-[libraries.kotlin-stdlib]
-module = "org.jetbrains.kotlin:kotlin-stdlib"
-version.ref = "kotlin-stdlib"
-
-[libraries.kotest-engine]
-module = "io.kotest:kotest-framework-engine"
-version.ref = "kotest"
-
-[libraries.kotest-assertions]
-module = "io.kotest:kotest-assertions-core"
-version.ref = "kotest"
-
-[libraries.kotest-junit-runner]
-module = "io.kotest:kotest-runner-junit5"
-version.ref = "kotest"
-
-[libraries.kotest-junit-reporter]
-module = "io.kotest:kotest-extensions-junitxml"
-version.ref = "kotest"
-
-[libraries.kotest-android-runner]
-module = "br.com.colman:kotest-runner-android"
-version = "1.1.1"
-
-[libraries.androidx-test-runner]
-module = "androidx.test:runner"
-version = "1.5.2"
-
-[libraries.dokka-base]
-module = "org.jetbrains.dokka:dokka-base"
-version.ref = "dokka"
-
-[plugins.kotlin-mpp]
-id = "org.jetbrains.kotlin.multiplatform"
-version.ref = "kotlin-stdlib"
-
-[plugins.android-library]
-id = "com.android.library"
-version.ref = "android-gradle"
-
-[plugins.kotest]
-id = "io.kotest.multiplatform"
-version.ref = "kotest"
-
-[plugins.dokka]
-id = "org.jetbrains.dokka"
-version.ref = "dokka"
-
-[plugins.gradle-publish]
-id = "com.gradle.plugin-publish"
-version = "1.2.1"
+kotlin-stdlib = "2.1.+"
+android-gradle = {strictly = "8.8.2"}
+kotest = "6.0.0.M3"
+dokka = "2.0.0"
+
+[libraries]
+kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin-stdlib" }
+kotest-engine = { module = "io.kotest:kotest-framework-engine", version.ref = "kotest" }
+kotest-assertions = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
+kotest-junit-runner = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }
+kotest-junit-reporter = { module = "io.kotest:kotest-extensions-junitxml", version.ref = "kotest" }
+kotest-android-runner = { module = "br.com.colman:kotest-runner-android", version = "1.1.1" }
+androidx-test-runner = { module = "androidx.test:runner", version = "1.6.2" }
+dokka-base = { module = "org.jetbrains.dokka:dokka-base", version.ref = "dokka" }
+
+[plugins]
+kotlin-mpp = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-stdlib" }
+android-library = { id = "com.android.library", version.ref = "android-gradle" }
+kotest = { id = "io.kotest.multiplatform", version.ref = "kotest" }
+dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
[bundles]
kotest-core = [
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index d64cd49..a4b76b9 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index b82aa23..94113f2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index 1aa94a4..f5feea6 100755
--- a/gradlew
+++ b/gradlew
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# SPDX-License-Identifier: Apache-2.0
+#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
diff --git a/gradlew.bat b/gradlew.bat
index 6689b85..9b42019 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
diff --git a/ktreesitter-plugin/README.md b/ktreesitter-plugin/README.md
index 0fdc9f3..21c6421 100644
--- a/ktreesitter-plugin/README.md
+++ b/ktreesitter-plugin/README.md
@@ -35,10 +35,5 @@ grammar {
className = "TreeSitterJava"
// The name of the package
packageName = "io.github.treesitter.ktreesitter.java"
- // The source files of the grammar
- files = arrayOf(
- baseDir.get().resolve("src/parser.c"),
- // baseDir.get().resolve("src/scanner.c")
- )
}
```
diff --git a/ktreesitter-plugin/build.gradle.kts b/ktreesitter-plugin/build.gradle.kts
index c22bc08..19d39b3 100644
--- a/ktreesitter-plugin/build.gradle.kts
+++ b/ktreesitter-plugin/build.gradle.kts
@@ -8,7 +8,7 @@ version = with(Properties()) {
plugins {
`java-gradle-plugin`
- id("com.gradle.plugin-publish") version "1.2.1"
+ id("com.gradle.plugin-publish") version "1.3.1"
}
repositories {
@@ -20,7 +20,6 @@ java {
targetCompatibility = JavaVersion.VERSION_17
}
-@Suppress("UnstableApiUsage")
gradlePlugin {
vcsUrl = "https://github.com/tree-sitter/kotlin-tree-sitter"
website = "https://github.com/tree-sitter/kotlin-tree-sitter/tree/master/ktreesitter-plugin"
diff --git a/ktreesitter-plugin/src/main/java/io/github/treesitter/ktreesitter/plugin/GrammarFilesTask.java b/ktreesitter-plugin/src/main/java/io/github/treesitter/ktreesitter/plugin/GrammarFilesTask.java
index bd35b28..e443c62 100644
--- a/ktreesitter-plugin/src/main/java/io/github/treesitter/ktreesitter/plugin/GrammarFilesTask.java
+++ b/ktreesitter-plugin/src/main/java/io/github/treesitter/ktreesitter/plugin/GrammarFilesTask.java
@@ -6,6 +6,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;
@@ -25,8 +26,6 @@ public abstract class GrammarFilesTask extends DefaultTask {
private String grammarName;
- private File[] grammarFiles;
-
private String interopName;
private String libraryName;
@@ -63,18 +62,6 @@ public final void setGrammarName(String grammarName) {
this.grammarName = grammarName;
}
- /** Get the source files of the grammar. */
- @InputFiles
- @PathSensitive(PathSensitivity.RELATIVE)
- public final File[] getGrammarFiles() {
- return grammarFiles;
- }
-
- /** Set the source files of the grammar. */
- public final void setGrammarFiles(File[] grammarFiles) {
- this.grammarFiles = grammarFiles;
- }
-
/** Get the name of the C interop def file. */
@Input
public final String getInteropName() {
@@ -281,9 +268,8 @@ jniPrefix, jniTransform(name), name
private void generateCmakeLists(Path srcDir) throws GradleException {
var jniBinding = srcDir.resolve("jni").resolve("binding.c");
- var files = Arrays.stream(grammarFiles).map(file -> relative(file.toPath()).toString());
var includeDir = relative(grammarDir.toPath().resolve("bindings/c"));
- var sources = relative(jniBinding) + " " + String.join(" ", files.toList());
+ var sources = String.format("%s %s", relative(jniBinding), srcFiles());
var template = readResource("CMakeLists.txt.in")
.replace("@LIBRARY@", libraryName)
.replace("@INCLUDE@", includeDir.toString())
@@ -305,6 +291,15 @@ private Path relative(Path file) {
return getGeneratedSrc().get().getAsFile().toPath().getParent().relativize(file);
}
+ private String srcFiles() {
+ var grammarSrcDir = grammarDir.toPath().resolve("src");
+ var scannerFile = grammarSrcDir.resolve("scanner.c");
+ if (!scannerFile.toFile().exists()) {
+ return grammarSrcDir.resolve("parser.c").toString();
+ }
+ return String.format("%s %s", grammarSrcDir.resolve("parser.c"), scannerFile);
+ }
+
private String readResource(String file) throws GradleException {
try (var stream = getClass().getResourceAsStream("/" + file)) {
var bytes = Objects.requireNonNull(stream).readAllBytes();
diff --git a/ktreesitter-plugin/src/main/java/io/github/treesitter/ktreesitter/plugin/GrammarPlugin.java b/ktreesitter-plugin/src/main/java/io/github/treesitter/ktreesitter/plugin/GrammarPlugin.java
index ef6953a..0bfc12f 100644
--- a/ktreesitter-plugin/src/main/java/io/github/treesitter/ktreesitter/plugin/GrammarPlugin.java
+++ b/ktreesitter-plugin/src/main/java/io/github/treesitter/ktreesitter/plugin/GrammarPlugin.java
@@ -30,7 +30,6 @@ public void apply(Project project) {
project.getTasks().register("generateGrammarFiles", GrammarFilesTask.class, it -> {
it.setGrammarDir(extension.getBaseDir().get());
it.setGrammarName(extension.getGrammarName().get());
- it.setGrammarFiles(extension.getFiles().get());
it.setInteropName(extension.getInteropName().get());
it.setLibraryName(extension.getLibraryName().get());
it.setPackageName(extension.getPackageName().get());
diff --git a/ktreesitter-plugin/src/main/resources/CMakeLists.txt.in b/ktreesitter-plugin/src/main/resources/CMakeLists.txt.in
index 067086f..67e8422 100644
--- a/ktreesitter-plugin/src/main/resources/CMakeLists.txt.in
+++ b/ktreesitter-plugin/src/main/resources/CMakeLists.txt.in
@@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.12.0)
-project(ktreesitter-java LANGUAGES C)
+project(@LIBRARY@ LANGUAGES C)
find_package(JNI REQUIRED)
@@ -10,12 +10,12 @@ set(CMAKE_C_STANDARD 11)
if(MSVC)
add_compile_options(/W3 /wd4244)
-else(MSVC)
+else()
set(CMAKE_C_VISIBILITY_PRESET hidden)
add_compile_options(-Wall -Wextra
-Wno-unused-parameter
-Werror=implicit-function-declaration)
-endif(MSVC)
+endif()
include_directories(${JNI_INCLUDE_DIRS} @INCLUDE@)
diff --git a/ktreesitter-plugin/src/main/resources/android.kt.in b/ktreesitter-plugin/src/main/resources/android.kt.in
index e24a6d0..27a4d2c 100644
--- a/ktreesitter-plugin/src/main/resources/android.kt.in
+++ b/ktreesitter-plugin/src/main/resources/android.kt.in
@@ -12,5 +12,4 @@ actual object @CLASS@ {
System.loadLibrary("@LIBRARY@")
}
-@METHODS@
-}
+@METHODS@}
diff --git a/ktreesitter-plugin/src/main/resources/jvm.kt.in b/ktreesitter-plugin/src/main/resources/jvm.kt.in
index 8a5b180..6021d01 100644
--- a/ktreesitter-plugin/src/main/resources/jvm.kt.in
+++ b/ktreesitter-plugin/src/main/resources/jvm.kt.in
@@ -20,7 +20,6 @@ actual object @CLASS@ {
}
@METHODS@
-
@JvmStatic
@Suppress("ConvertToStringTemplate")
@Throws(UnsupportedOperationException::class)
diff --git a/ktreesitter/CMakeLists.txt b/ktreesitter/CMakeLists.txt
index fdc786f..0e1d75c 100644
--- a/ktreesitter/CMakeLists.txt
+++ b/ktreesitter/CMakeLists.txt
@@ -11,20 +11,20 @@ set(CMAKE_C_STANDARD 11)
if(MSVC)
add_compile_options(/W3 /wd4244)
-else(MSVC)
+else()
set(CMAKE_C_VISIBILITY_PRESET hidden)
add_compile_options(-Wall -Wextra
-Wno-unused-parameter
-Wno-cast-function-type
-Werror=incompatible-pointer-types
-Werror=implicit-function-declaration)
-endif(MSVC)
+endif()
include_directories(${JNI_INCLUDE_DIRS}
../tree-sitter/lib/src
../tree-sitter/lib/include)
-add_compile_definitions(TREE_SITTER_HIDE_SYMBOLS)
+add_compile_definitions(TREE_SITTER_HIDE_SYMBOLS _DEFAULT_SOURCE _POSIX_C_SOURCE=200112L)
add_library(ktreesitter SHARED
./src/jni/language.c
@@ -32,6 +32,7 @@ add_library(ktreesitter SHARED
./src/jni/node.c
./src/jni/parser.c
./src/jni/query.c
+ ./src/jni/query_cursor.c
./src/jni/tree.c
./src/jni/tree_cursor.c
./src/jni/module.c
diff --git a/ktreesitter/build.gradle.kts b/ktreesitter/build.gradle.kts
index b2acb3b..d97adf3 100644
--- a/ktreesitter/build.gradle.kts
+++ b/ktreesitter/build.gradle.kts
@@ -1,18 +1,28 @@
import java.io.OutputStream.nullOutputStream
-import java.net.URI
import org.gradle.internal.os.OperatingSystem
import org.gradle.kotlin.dsl.support.useToRun
-import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.DokkaBaseConfiguration
+import org.jetbrains.dokka.gradle.tasks.DokkaGeneratePublicationTask
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
-import org.jetbrains.kotlin.konan.target.PlatformManager
inline val File.unixPath: String
get() = if (!os.isWindows) path else path.replace("\\", "/")
+fun KotlinNativeTarget.treesitter() {
+ compilations.configureEach {
+ cinterops.create("treesitter") {
+ val srcDir = treesitterDir.resolve("lib/src")
+ val includeDir = treesitterDir.resolve("lib/include")
+ includeDirs.allHeaders(srcDir, includeDir)
+ includeDirs.headerFilterOnly(includeDir)
+ extraOpts("-libraryPath", libsDir.dir(konanTarget.name))
+ }
+ }
+}
+
val os: OperatingSystem = OperatingSystem.current()
val libsDir = layout.buildDirectory.get().dir("libs")
val treesitterDir = rootDir.resolve("tree-sitter")
@@ -34,6 +44,10 @@ buildscript {
}
}
+dependencyLocking {
+ lockAllConfigurations()
+}
+
kotlin {
jvm {}
@@ -42,30 +56,15 @@ kotlin {
publishLibraryVariants("release")
}
- when {
- os.isLinux -> listOf(linuxX64(), linuxArm64())
- os.isWindows -> listOf(mingwX64())
- os.isMacOsX -> listOf(
- macosArm64(),
- macosX64(),
- iosArm64(),
- iosSimulatorArm64()
- )
- else -> {
- val arch = System.getProperty("os.arch")
- throw GradleException("Unsupported platform: $os ($arch)")
- }
- }.forEach { target ->
- target.compilations.configureEach {
- cinterops.create("treesitter") {
- val srcDir = treesitterDir.resolve("lib/src")
- val includeDir = treesitterDir.resolve("lib/include")
- includeDirs.allHeaders(srcDir, includeDir)
- includeDirs.headerFilterOnly(includeDir)
- extraOpts("-libraryPath", libsDir.dir(konanTarget.name))
- }
- }
- }
+ linuxX64 { treesitter() }
+ linuxArm64 { treesitter() }
+ mingwX64 { treesitter() }
+ macosArm64 { treesitter() }
+ macosX64 { treesitter() }
+ iosArm64 { treesitter() }
+ iosSimulatorArm64 { treesitter() }
+
+ applyDefaultHierarchyTemplate()
jvmToolchain(17)
@@ -117,7 +116,6 @@ android {
defaultConfig {
minSdk = (property("sdk.version.min") as String).toInt()
ndk {
- moduleName = "ktreesitter"
//noinspection ChromeOsAbiSupport
abiFilters += setOf("x86_64", "arm64-v8a", "armeabi-v7a")
}
@@ -214,31 +212,33 @@ signing {
sign(publishing.publications)
}
-tasks.dokkaHtml {
+dokka {
val tmpDir = layout.buildDirectory.get().dir("tmp")
val ref = System.getenv("GITHUB_SHA")?.subSequence(0, 7) ?: "master"
val url = "https://github.com/tree-sitter/kotlin-tree-sitter/blob/$ref/ktreesitter"
- inputs.file(file("README.md"))
-
moduleName.set("KTreeSitter")
- pluginConfiguration {
+ pluginsConfiguration.html {
footerMessage = "© 2024 tree-sitter"
homepageLink = "https://tree-sitter.github.io/tree-sitter/"
- customAssets = listOf(rootDir.resolve("gradle/logo-icon.svg"))
+ customAssets.from(rootDir.resolve("gradle/logo-icon.svg"))
}
dokkaSourceSets.configureEach {
jdkVersion.set(17)
- noStdlibLink.set(true)
includes.from(tmpDir.file("README.md"))
- externalDocumentationLink("https://kotlinlang.org/api/core/")
sourceLink {
+ remoteUrl(url)
localDirectory.set(projectDir)
- remoteUrl.set(URI.create(url).toURL())
}
}
+}
+
+tasks.withType {
+ val tmpDir = layout.buildDirectory.get().dir("tmp")
+
+ inputs.file("README.md")
doFirst {
copy {
@@ -264,6 +264,8 @@ tasks.withType().configureEach {
}
}
+// TODO: replace with cmake
+@Suppress("DEPRECATION")
tasks.withType().configureEach {
if (name.startsWith("cinteropTest")) return@configureEach
@@ -273,17 +275,16 @@ tasks.withType().configureEach {
"${konanTarget.family.staticPrefix}tree-sitter.${konanTarget.family.staticSuffix}"
).asFile
val objectFile = treesitterDir.resolve("lib.o")
- val loader = PlatformManager(konanHome.get(), false, konanDataDir.orNull).loader(konanTarget)
doFirst {
- if (!File(loader.absoluteTargetToolchain).isDirectory) loader.downloadDependencies()
-
val argsFile = File.createTempFile("args", null)
argsFile.deleteOnExit()
argsFile.writer().useToRun {
write("-I" + treesitterDir.resolve("lib/src").unixPath + "\n")
write("-I" + treesitterDir.resolve("lib/include").unixPath + "\n")
write("-DTREE_SITTER_HIDE_SYMBOLS\n")
+ write("-D_DEFAULT_SOURCE\n")
+ write("-D_POSIX_C_SOURCE=200112L\n")
write("-fvisibility=hidden\n")
write("-std=c11\n")
write("-O2\n")
diff --git a/ktreesitter/gradle.lockfile b/ktreesitter/gradle.lockfile
new file mode 100644
index 0000000..6be66b0
--- /dev/null
+++ b/ktreesitter/gradle.lockfile
@@ -0,0 +1,235 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.annotation:annotation-jvm:1.7.0-beta01=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+androidx.annotation:annotation:1.7.0-beta01=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+androidx.test.services:storage:1.5.0=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+androidx.test:monitor:1.7.2=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+androidx.test:runner:1.6.2=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+androidx.tracing:tracing:1.1.0=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+br.com.colman:kotest-runner-android:1.1.1=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+com.android.tools.ddms:ddmlib:31.8.2=_internal-unified-test-platform-android-device-provider-ddmlib
+com.android.tools.emulator:proto:31.8.2=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention
+com.android.tools.utp:android-device-provider-ddmlib-proto:31.8.2=_internal-unified-test-platform-android-device-provider-ddmlib
+com.android.tools.utp:android-device-provider-ddmlib:31.8.2=_internal-unified-test-platform-android-device-provider-ddmlib
+com.android.tools.utp:android-device-provider-gradle-proto:31.8.2=_internal-unified-test-platform-android-device-provider-gradle
+com.android.tools.utp:android-device-provider-gradle:31.8.2=_internal-unified-test-platform-android-device-provider-gradle
+com.android.tools.utp:android-device-provider-profile-proto:31.8.2=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle
+com.android.tools.utp:android-device-provider-profile:31.8.2=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.8.2=_internal-unified-test-platform-android-test-plugin-host-additional-test-output
+com.android.tools.utp:android-test-plugin-host-additional-test-output:31.8.2=_internal-unified-test-platform-android-test-plugin-host-additional-test-output
+com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.8.2=_internal-unified-test-platform-android-test-plugin-host-apk-installer
+com.android.tools.utp:android-test-plugin-host-apk-installer:31.8.2=_internal-unified-test-platform-android-test-plugin-host-apk-installer
+com.android.tools.utp:android-test-plugin-host-coverage-proto:31.8.2=_internal-unified-test-platform-android-test-plugin-host-coverage
+com.android.tools.utp:android-test-plugin-host-coverage:31.8.2=_internal-unified-test-platform-android-test-plugin-host-coverage
+com.android.tools.utp:android-test-plugin-host-device-info-proto:31.8.2=_internal-unified-test-platform-android-test-plugin-host-device-info
+com.android.tools.utp:android-test-plugin-host-device-info:31.8.2=_internal-unified-test-platform-android-test-plugin-host-device-info
+com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.8.2=_internal-unified-test-platform-android-test-plugin-host-emulator-control
+com.android.tools.utp:android-test-plugin-host-emulator-control:31.8.2=_internal-unified-test-platform-android-test-plugin-host-emulator-control
+com.android.tools.utp:android-test-plugin-host-logcat-proto:31.8.2=_internal-unified-test-platform-android-test-plugin-host-logcat
+com.android.tools.utp:android-test-plugin-host-logcat:31.8.2=_internal-unified-test-platform-android-test-plugin-host-logcat
+com.android.tools.utp:android-test-plugin-host-retention-proto:31.8.2=_internal-unified-test-platform-android-test-plugin-host-retention
+com.android.tools.utp:android-test-plugin-host-retention:31.8.2=_internal-unified-test-platform-android-test-plugin-host-retention
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.8.2=_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.android.tools.utp:android-test-plugin-result-listener-gradle:31.8.2=_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.android.tools.utp:utp-common:31.8.2=_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention
+com.android.tools:annotations:31.8.2=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.android.tools:common:31.8.2=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.fasterxml.jackson.core:jackson-annotations:2.12.7=dokkaHtmlGeneratorRuntimeResolver~internal
+com.fasterxml.jackson.core:jackson-core:2.12.7=dokkaHtmlGeneratorRuntimeResolver~internal
+com.fasterxml.jackson.core:jackson-databind:2.12.7.1=dokkaHtmlGeneratorRuntimeResolver~internal
+com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.12.7=dokkaHtmlGeneratorRuntimeResolver~internal
+com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.7=dokkaHtmlGeneratorRuntimeResolver~internal
+com.fasterxml.jackson.module:jackson-module-kotlin:2.12.7=dokkaHtmlGeneratorRuntimeResolver~internal
+com.fasterxml.jackson:jackson-bom:2.12.7=dokkaHtmlGeneratorRuntimeResolver~internal
+com.fasterxml.woodstox:woodstox-core:6.2.4=dokkaHtmlGeneratorRuntimeResolver~internal
+com.github.ajalt:colormath:1.2.0=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.github.ajalt:mordant:1.2.1=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.android:annotations:4.1.1.4=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.api.grpc:proto-google-common-protos:2.17.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.code.findbugs:jsr305:3.0.2=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.code.gson:gson:2.10.1=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.crypto.tink:tink:1.7.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control
+com.google.errorprone:error_prone_annotations:2.18.0=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.guava:failureaccess:1.0.1=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.guava:guava:32.0.1-jre=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.j2objc:j2objc-annotations:2.8=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.protobuf:protobuf-java:3.22.3=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.testing.platform:android-device-provider-local:0.0.9-alpha02=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.testing.platform:android-driver-instrumentation:0.0.9-alpha02=_internal-unified-test-platform-android-driver-instrumentation,_internal-unified-test-platform-android-test-plugin-host-emulator-control
+com.google.testing.platform:android-test-plugin:0.0.9-alpha02=_internal-unified-test-platform-android-test-plugin
+com.google.testing.platform:core-proto:0.0.9-alpha02=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+com.google.testing.platform:core:0.0.9-alpha02=_internal-unified-test-platform-core
+com.google.testing.platform:launcher:0.0.9-alpha02=_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-launcher
+commons-io:commons-io:2.13.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention
+io.github.classgraph:classgraph:4.8.172=androidDebugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeClasspath
+io.github.java-diff-utils:java-diff-utils:4.12=androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestRuntimeClasspath,jvmTestRuntimeClasspath,releaseUnitTestRuntimeClasspath
+io.grpc:grpc-api:1.57.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.grpc:grpc-context:1.57.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.grpc:grpc-core:1.57.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.grpc:grpc-netty:1.57.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.grpc:grpc-protobuf-lite:1.57.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.grpc:grpc-protobuf:1.57.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.grpc:grpc-stub:1.57.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.kotest:kotest-assertions-core-iosarm64:6.0.0.M3=iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries
+io.kotest:kotest-assertions-core-iossimulatorarm64:6.0.0.M3=iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries
+io.kotest:kotest-assertions-core-jvm:6.0.0.M3=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+io.kotest:kotest-assertions-core-linuxarm64:6.0.0.M3=linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries
+io.kotest:kotest-assertions-core-linuxx64:6.0.0.M3=linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries
+io.kotest:kotest-assertions-core-macosarm64:6.0.0.M3=macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries
+io.kotest:kotest-assertions-core-macosx64:6.0.0.M3=macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries
+io.kotest:kotest-assertions-core-mingwx64:6.0.0.M3=mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries
+io.kotest:kotest-assertions-core:6.0.0.M3=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,iosArm64TestApiDependenciesMetadata,iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosArm64TestCompileOnlyDependenciesMetadata,iosArm64TestImplementationDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestApiDependenciesMetadata,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,iosSimulatorArm64TestCompileOnlyDependenciesMetadata,iosSimulatorArm64TestImplementationDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,linuxArm64TestApiDependenciesMetadata,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxArm64TestCompileOnlyDependenciesMetadata,linuxArm64TestImplementationDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestApiDependenciesMetadata,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,linuxX64TestCompileOnlyDependenciesMetadata,linuxX64TestImplementationDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestApiDependenciesMetadata,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosArm64TestCompileOnlyDependenciesMetadata,macosArm64TestImplementationDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestApiDependenciesMetadata,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,macosX64TestCompileOnlyDependenciesMetadata,macosX64TestImplementationDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestApiDependenciesMetadata,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries,mingwX64TestCompileOnlyDependenciesMetadata,mingwX64TestImplementationDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+io.kotest:kotest-assertions-shared-iosarm64:6.0.0.M3=iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries
+io.kotest:kotest-assertions-shared-iossimulatorarm64:6.0.0.M3=iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries
+io.kotest:kotest-assertions-shared-jvm:6.0.0.M3=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+io.kotest:kotest-assertions-shared-linuxarm64:6.0.0.M3=linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries
+io.kotest:kotest-assertions-shared-linuxx64:6.0.0.M3=linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries
+io.kotest:kotest-assertions-shared-macosarm64:6.0.0.M3=macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries
+io.kotest:kotest-assertions-shared-macosx64:6.0.0.M3=macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries
+io.kotest:kotest-assertions-shared-mingwx64:6.0.0.M3=mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries
+io.kotest:kotest-assertions-shared:6.0.0.M3=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,iosArm64TestApiDependenciesMetadata,iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosArm64TestCompileOnlyDependenciesMetadata,iosArm64TestImplementationDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestApiDependenciesMetadata,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,iosSimulatorArm64TestCompileOnlyDependenciesMetadata,iosSimulatorArm64TestImplementationDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,linuxArm64TestApiDependenciesMetadata,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxArm64TestCompileOnlyDependenciesMetadata,linuxArm64TestImplementationDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestApiDependenciesMetadata,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,linuxX64TestCompileOnlyDependenciesMetadata,linuxX64TestImplementationDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestApiDependenciesMetadata,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosArm64TestCompileOnlyDependenciesMetadata,macosArm64TestImplementationDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestApiDependenciesMetadata,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,macosX64TestCompileOnlyDependenciesMetadata,macosX64TestImplementationDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestApiDependenciesMetadata,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries,mingwX64TestCompileOnlyDependenciesMetadata,mingwX64TestImplementationDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+io.kotest:kotest-common-iosarm64:6.0.0.M3=iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries
+io.kotest:kotest-common-iossimulatorarm64:6.0.0.M3=iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries
+io.kotest:kotest-common-jvm:6.0.0.M3=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+io.kotest:kotest-common-linuxarm64:6.0.0.M3=linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries
+io.kotest:kotest-common-linuxx64:6.0.0.M3=linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries
+io.kotest:kotest-common-macosarm64:6.0.0.M3=macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries
+io.kotest:kotest-common-macosx64:6.0.0.M3=macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries
+io.kotest:kotest-common-mingwx64:6.0.0.M3=mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries
+io.kotest:kotest-common:6.0.0.M3=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,iosArm64TestApiDependenciesMetadata,iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosArm64TestCompileOnlyDependenciesMetadata,iosArm64TestImplementationDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestApiDependenciesMetadata,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,iosSimulatorArm64TestCompileOnlyDependenciesMetadata,iosSimulatorArm64TestImplementationDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,linuxArm64TestApiDependenciesMetadata,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxArm64TestCompileOnlyDependenciesMetadata,linuxArm64TestImplementationDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestApiDependenciesMetadata,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,linuxX64TestCompileOnlyDependenciesMetadata,linuxX64TestImplementationDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestApiDependenciesMetadata,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosArm64TestCompileOnlyDependenciesMetadata,macosArm64TestImplementationDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestApiDependenciesMetadata,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,macosX64TestCompileOnlyDependenciesMetadata,macosX64TestImplementationDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestApiDependenciesMetadata,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries,mingwX64TestCompileOnlyDependenciesMetadata,mingwX64TestImplementationDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+io.kotest:kotest-extensions-junitxml-jvm:6.0.0.M3=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+io.kotest:kotest-extensions-junitxml:6.0.0.M3=allTestSourceSetsCompileDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
+io.kotest:kotest-extensions-jvm:6.0.0.M3=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+io.kotest:kotest-extensions:6.0.0.M3=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+io.kotest:kotest-framework-discovery-jvm:5.9.0=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+io.kotest:kotest-framework-discovery:5.9.0=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+io.kotest:kotest-framework-engine-iosarm64:6.0.0.M3=iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries
+io.kotest:kotest-framework-engine-iossimulatorarm64:6.0.0.M3=iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries
+io.kotest:kotest-framework-engine-jvm:6.0.0.M3=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+io.kotest:kotest-framework-engine-linuxarm64:6.0.0.M3=linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries
+io.kotest:kotest-framework-engine-linuxx64:6.0.0.M3=linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries
+io.kotest:kotest-framework-engine-macosarm64:6.0.0.M3=macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries
+io.kotest:kotest-framework-engine-macosx64:6.0.0.M3=macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries
+io.kotest:kotest-framework-engine-mingwx64:6.0.0.M3=mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries
+io.kotest:kotest-framework-engine:6.0.0.M3=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,iosArm64TestApiDependenciesMetadata,iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosArm64TestCompileOnlyDependenciesMetadata,iosArm64TestImplementationDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestApiDependenciesMetadata,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,iosSimulatorArm64TestCompileOnlyDependenciesMetadata,iosSimulatorArm64TestImplementationDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,linuxArm64TestApiDependenciesMetadata,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxArm64TestCompileOnlyDependenciesMetadata,linuxArm64TestImplementationDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestApiDependenciesMetadata,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,linuxX64TestCompileOnlyDependenciesMetadata,linuxX64TestImplementationDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestApiDependenciesMetadata,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosArm64TestCompileOnlyDependenciesMetadata,macosArm64TestImplementationDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestApiDependenciesMetadata,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,macosX64TestCompileOnlyDependenciesMetadata,macosX64TestImplementationDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestApiDependenciesMetadata,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries,mingwX64TestCompileOnlyDependenciesMetadata,mingwX64TestImplementationDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+io.kotest:kotest-framework-multiplatform-plugin-embeddable-compiler-jvm:6.0.0.M3=kotlinCompilerPluginClasspathIosArm64Main,kotlinCompilerPluginClasspathIosArm64Test,kotlinCompilerPluginClasspathIosSimulatorArm64Main,kotlinCompilerPluginClasspathIosSimulatorArm64Test,kotlinCompilerPluginClasspathLinuxArm64Main,kotlinCompilerPluginClasspathLinuxArm64Test,kotlinCompilerPluginClasspathLinuxX64Main,kotlinCompilerPluginClasspathLinuxX64Test,kotlinCompilerPluginClasspathMacosArm64Main,kotlinCompilerPluginClasspathMacosArm64Test,kotlinCompilerPluginClasspathMacosX64Main,kotlinCompilerPluginClasspathMacosX64Test,kotlinCompilerPluginClasspathMetadataAppleMain,kotlinCompilerPluginClasspathMetadataIosMain,kotlinCompilerPluginClasspathMetadataLinuxMain,kotlinCompilerPluginClasspathMetadataMacosMain,kotlinCompilerPluginClasspathMetadataNativeMain,kotlinCompilerPluginClasspathMingwX64Main,kotlinCompilerPluginClasspathMingwX64Test
+io.kotest:kotest-framework-multiplatform-plugin-embeddable-compiler:6.0.0.M3=kotlinCompilerPluginClasspathIosArm64Main,kotlinCompilerPluginClasspathIosArm64Test,kotlinCompilerPluginClasspathIosSimulatorArm64Main,kotlinCompilerPluginClasspathIosSimulatorArm64Test,kotlinCompilerPluginClasspathLinuxArm64Main,kotlinCompilerPluginClasspathLinuxArm64Test,kotlinCompilerPluginClasspathLinuxX64Main,kotlinCompilerPluginClasspathLinuxX64Test,kotlinCompilerPluginClasspathMacosArm64Main,kotlinCompilerPluginClasspathMacosArm64Test,kotlinCompilerPluginClasspathMacosX64Main,kotlinCompilerPluginClasspathMacosX64Test,kotlinCompilerPluginClasspathMetadataAppleMain,kotlinCompilerPluginClasspathMetadataIosMain,kotlinCompilerPluginClasspathMetadataLinuxMain,kotlinCompilerPluginClasspathMetadataMacosMain,kotlinCompilerPluginClasspathMetadataNativeMain,kotlinCompilerPluginClasspathMingwX64Main,kotlinCompilerPluginClasspathMingwX64Test
+io.kotest:kotest-runner-junit5-jvm:6.0.0.M3=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+io.kotest:kotest-runner-junit5:6.0.0.M3=allTestSourceSetsCompileDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
+io.netty:netty-buffer:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-codec-http2:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-codec-http:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-codec-socks:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-codec:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-common:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-handler-proxy:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-handler:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-resolver:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-transport-native-unix-common:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.netty:netty-transport:4.1.93.Final=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+io.perfmark:perfmark-api:0.26.0=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+jakarta.activation:jakarta.activation-api:1.2.1=dokkaHtmlGeneratorRuntimeResolver~internal
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=dokkaHtmlGeneratorRuntimeResolver~internal
+javax.annotation:javax.annotation-api:1.3.2=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+junit:junit:4.13.2=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+net.bytebuddy:byte-buddy-agent:1.10.9=androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestRuntimeClasspath,jvmTestRuntimeClasspath,releaseUnitTestRuntimeClasspath
+net.bytebuddy:byte-buddy:1.10.9=androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestRuntimeClasspath,jvmTestRuntimeClasspath,releaseUnitTestRuntimeClasspath
+net.java.dev.jna:jna-platform:5.6.0=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+net.java.dev.jna:jna-platform:5.9.0=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+net.java.dev.jna:jna:5.6.0=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+net.java.dev.jna:jna:5.9.0=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+net.sf.kxml:kxml2:2.3.0=_internal-unified-test-platform-android-device-provider-ddmlib
+org.apache.commons:commons-lang3:3.13.0=androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestRuntimeClasspath,jvmTestRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.apiguardian:apiguardian-api:1.1.2=jvmTestCompileClasspath
+org.checkerframework:checker-qual:3.33.0=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.codehaus.mojo:animal-sniffer-annotations:1.23=_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.codehaus.woodstox:stax2-api:4.2.1=dokkaHtmlGeneratorRuntimeResolver~internal
+org.freemarker:freemarker:2.3.32=dokkaHtmlGeneratorRuntimeResolver~internal
+org.hamcrest:hamcrest-core:1.3=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
+org.jdom:jdom2:2.0.6.1=jvmTestRuntimeClasspath
+org.jetbrains.dokka:analysis-kotlin-descriptors:2.0.0=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.dokka:analysis-markdown:2.0.0=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.dokka:dokka-base:2.0.0=dokkaHtmlGeneratorRuntimeResolver~internal,dokkaHtmlPluginIntransitiveResolver~internal
+org.jetbrains.dokka:dokka-core:2.0.0=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.dokka:templating-plugin:2.0.0=dokkaHtmlGeneratorRuntimeResolver~internal,dokkaHtmlPluginIntransitiveResolver~internal
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-build-tools-api:2.1.21=kotlinBuildToolsApiClasspath
+org.jetbrains.kotlin:kotlin-build-tools-impl:2.1.21=kotlinBuildToolsApiClasspath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:2.1.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-compiler-runner:2.1.21=kotlinBuildToolsApiClasspath
+org.jetbrains.kotlin:kotlin-daemon-client:2.1.21=kotlinBuildToolsApiClasspath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:2.1.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.1.21=kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-native-prebuilt:2.1.21=kotlinNativeBundleConfiguration
+org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-reflect:2.0.20=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.kotlin:kotlin-reflect:2.1.20=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidReleaseUnitTestRuntimeClasspath,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugUnitTestRuntimeClasspath,iosArm64TestApiDependenciesMetadata,iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosArm64TestCompileOnlyDependenciesMetadata,iosArm64TestImplementationDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestApiDependenciesMetadata,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,iosSimulatorArm64TestCompileOnlyDependenciesMetadata,iosSimulatorArm64TestImplementationDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,linuxArm64TestApiDependenciesMetadata,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxArm64TestCompileOnlyDependenciesMetadata,linuxArm64TestImplementationDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestApiDependenciesMetadata,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,linuxX64TestCompileOnlyDependenciesMetadata,linuxX64TestImplementationDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestApiDependenciesMetadata,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosArm64TestCompileOnlyDependenciesMetadata,macosArm64TestImplementationDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestApiDependenciesMetadata,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,macosX64TestCompileOnlyDependenciesMetadata,macosX64TestImplementationDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestApiDependenciesMetadata,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries,mingwX64TestCompileOnlyDependenciesMetadata,mingwX64TestImplementationDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-script-runtime:2.1.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathAndroidDebug,kotlinCompilerPluginClasspathAndroidDebugAndroidTest,kotlinCompilerPluginClasspathAndroidDebugUnitTest,kotlinCompilerPluginClasspathAndroidRelease,kotlinCompilerPluginClasspathAndroidReleaseUnitTest,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-scripting-common:2.1.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathAndroidDebug,kotlinCompilerPluginClasspathAndroidDebugAndroidTest,kotlinCompilerPluginClasspathAndroidDebugUnitTest,kotlinCompilerPluginClasspathAndroidRelease,kotlinCompilerPluginClasspathAndroidReleaseUnitTest,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.1.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathAndroidDebug,kotlinCompilerPluginClasspathAndroidDebugAndroidTest,kotlinCompilerPluginClasspathAndroidDebugUnitTest,kotlinCompilerPluginClasspathAndroidRelease,kotlinCompilerPluginClasspathAndroidReleaseUnitTest,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.1.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathAndroidDebug,kotlinCompilerPluginClasspathAndroidDebugAndroidTest,kotlinCompilerPluginClasspathAndroidDebugUnitTest,kotlinCompilerPluginClasspathAndroidRelease,kotlinCompilerPluginClasspathAndroidReleaseUnitTest,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain
+org.jetbrains.kotlin:kotlin-scripting-jvm:2.1.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathAndroidDebug,kotlinCompilerPluginClasspathAndroidDebugAndroidTest,kotlinCompilerPluginClasspathAndroidDebugUnitTest,kotlinCompilerPluginClasspathAndroidRelease,kotlinCompilerPluginClasspathAndroidReleaseUnitTest,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain
+org.jetbrains.kotlin:kotlin-stdlib-common:2.0.20=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.kotlin:kotlin-stdlib-common:2.0.21=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.jetbrains.kotlin:kotlin-stdlib-common:2.1.21=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.0.21=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=allInstrumentedTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.jetbrains.kotlin:kotlin-stdlib:2.0.20=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.kotlin:kotlin-stdlib:2.0.21=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.jetbrains.kotlin:kotlin-stdlib:2.1.20=kotlinCompilerPluginClasspathMetadataAppleMain,kotlinCompilerPluginClasspathMetadataIosMain,kotlinCompilerPluginClasspathMetadataLinuxMain,kotlinCompilerPluginClasspathMetadataMacosMain,kotlinCompilerPluginClasspathMetadataNativeMain
+org.jetbrains.kotlin:kotlin-stdlib:2.1.21=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugApiDependenciesMetadata,androidDebugCompileClasspath,androidDebugCompileOnlyDependenciesMetadata,androidDebugImplementationDependenciesMetadata,androidDebugResolvableDependenciesMetadata,androidDebugRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestDebugApiDependenciesMetadata,androidInstrumentedTestDebugCompileOnlyDependenciesMetadata,androidInstrumentedTestDebugImplementationDependenciesMetadata,androidInstrumentedTestDebugResolvableDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidMainApiDependenciesMetadata,androidMainCompileOnlyDependenciesMetadata,androidMainImplementationDependenciesMetadata,androidMainResolvableDependenciesMetadata,androidReleaseApiDependenciesMetadata,androidReleaseCompileClasspath,androidReleaseCompileOnlyDependenciesMetadata,androidReleaseImplementationDependenciesMetadata,androidReleaseResolvableDependenciesMetadata,androidReleaseRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,iosArm64CInterop,iosArm64CompilationDependenciesMetadata,iosArm64CompileKlibraries,iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosSimulatorArm64CInterop,iosSimulatorArm64CompilationDependenciesMetadata,iosSimulatorArm64CompileKlibraries,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileClasspath,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmMainRuntimeClasspath,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathAndroidDebug,kotlinCompilerPluginClasspathAndroidDebugAndroidTest,kotlinCompilerPluginClasspathAndroidDebugUnitTest,kotlinCompilerPluginClasspathAndroidRelease,kotlinCompilerPluginClasspathAndroidReleaseUnitTest,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,linuxArm64CInterop,linuxArm64CompilationDependenciesMetadata,linuxArm64CompileKlibraries,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxX64CInterop,linuxX64CompilationDependenciesMetadata,linuxX64CompileKlibraries,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,macosArm64CInterop,macosArm64CompilationDependenciesMetadata,macosArm64CompileKlibraries,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosX64CInterop,macosX64CompilationDependenciesMetadata,macosX64CompileKlibraries,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,metadataAppleMainCompileClasspath,metadataCommonMainCompileClasspath,metadataCompileClasspath,metadataIosMainCompileClasspath,metadataLinuxMainCompileClasspath,metadataMacosMainCompileClasspath,metadataNativeMainCompileClasspath,mingwX64CInterop,mingwX64CompilationDependenciesMetadata,mingwX64CompileKlibraries,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:atomicfu-iosarm64:0.26.1=iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries
+org.jetbrains.kotlinx:atomicfu-iossimulatorarm64:0.26.1=iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries
+org.jetbrains.kotlinx:atomicfu-linuxarm64:0.26.1=linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries
+org.jetbrains.kotlinx:atomicfu-linuxx64:0.26.1=linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries
+org.jetbrains.kotlinx:atomicfu-macosarm64:0.26.1=macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries
+org.jetbrains.kotlinx:atomicfu-macosx64:0.26.1=macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries
+org.jetbrains.kotlinx:atomicfu-mingwx64:0.26.1=mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries
+org.jetbrains.kotlinx:atomicfu:0.23.1=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,iosArm64TestApiDependenciesMetadata,iosArm64TestCompileOnlyDependenciesMetadata,iosArm64TestImplementationDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestApiDependenciesMetadata,iosSimulatorArm64TestCompileOnlyDependenciesMetadata,iosSimulatorArm64TestImplementationDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,linuxArm64TestApiDependenciesMetadata,linuxArm64TestCompileOnlyDependenciesMetadata,linuxArm64TestImplementationDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestApiDependenciesMetadata,linuxX64TestCompileOnlyDependenciesMetadata,linuxX64TestImplementationDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestApiDependenciesMetadata,macosArm64TestCompileOnlyDependenciesMetadata,macosArm64TestImplementationDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestApiDependenciesMetadata,macosX64TestCompileOnlyDependenciesMetadata,macosX64TestImplementationDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestApiDependenciesMetadata,mingwX64TestCompileOnlyDependenciesMetadata,mingwX64TestImplementationDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata
+org.jetbrains.kotlinx:atomicfu:0.26.1=iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.0=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.kotlinx:kotlinx-coroutines-core-iosarm64:1.10.0=iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-core-iossimulatorarm64:1.10.0=iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.0=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-linuxarm64:1.10.0=linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-core-linuxx64:1.10.0=linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-core-macosarm64:1.10.0=macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-core-macosx64:1.10.0=macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-core-mingwx64:1.10.0=mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.0=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,iosArm64TestApiDependenciesMetadata,iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosArm64TestCompileOnlyDependenciesMetadata,iosArm64TestImplementationDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestApiDependenciesMetadata,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,iosSimulatorArm64TestCompileOnlyDependenciesMetadata,iosSimulatorArm64TestImplementationDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,linuxArm64TestApiDependenciesMetadata,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxArm64TestCompileOnlyDependenciesMetadata,linuxArm64TestImplementationDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestApiDependenciesMetadata,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,linuxX64TestCompileOnlyDependenciesMetadata,linuxX64TestImplementationDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestApiDependenciesMetadata,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosArm64TestCompileOnlyDependenciesMetadata,macosArm64TestImplementationDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestApiDependenciesMetadata,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,macosX64TestCompileOnlyDependenciesMetadata,macosX64TestImplementationDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestApiDependenciesMetadata,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries,mingwX64TestCompileOnlyDependenciesMetadata,mingwX64TestImplementationDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains.kotlinx:kotlinx-coroutines-debug:1.10.0=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.10.0=androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestRuntimeClasspath,jvmTestRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-test-iosarm64:1.10.0=iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-test-iossimulatorarm64:1.10.0=iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.10.0=androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestRuntimeClasspath,jvmTestRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-test-linuxarm64:1.10.0=linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-test-linuxx64:1.10.0=linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-test-macosarm64:1.10.0=macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-test-macosx64:1.10.0=macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-test-mingwx64:1.10.0=mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries
+org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.0=allInstrumentedTestSourceSetsCompileDependenciesMetadata,allTestSourceSetsCompileDependenciesMetadata,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestRuntimeClasspath,androidInstrumentedTestApiDependenciesMetadata,androidInstrumentedTestCompileOnlyDependenciesMetadata,androidInstrumentedTestImplementationDependenciesMetadata,androidInstrumentedTestResolvableDependenciesMetadata,androidReleaseUnitTestRuntimeClasspath,androidUnitTestApiDependenciesMetadata,androidUnitTestCompileOnlyDependenciesMetadata,androidUnitTestDebugApiDependenciesMetadata,androidUnitTestDebugCompileOnlyDependenciesMetadata,androidUnitTestDebugImplementationDependenciesMetadata,androidUnitTestDebugResolvableDependenciesMetadata,androidUnitTestImplementationDependenciesMetadata,androidUnitTestReleaseApiDependenciesMetadata,androidUnitTestReleaseCompileOnlyDependenciesMetadata,androidUnitTestReleaseImplementationDependenciesMetadata,androidUnitTestReleaseResolvableDependenciesMetadata,androidUnitTestResolvableDependenciesMetadata,appleTestApiDependenciesMetadata,appleTestCompileOnlyDependenciesMetadata,appleTestImplementationDependenciesMetadata,appleTestResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugUnitTestRuntimeClasspath,iosArm64TestApiDependenciesMetadata,iosArm64TestCInterop,iosArm64TestCompilationDependenciesMetadata,iosArm64TestCompileKlibraries,iosArm64TestCompileOnlyDependenciesMetadata,iosArm64TestImplementationDependenciesMetadata,iosArm64TestResolvableDependenciesMetadata,iosSimulatorArm64TestApiDependenciesMetadata,iosSimulatorArm64TestCInterop,iosSimulatorArm64TestCompilationDependenciesMetadata,iosSimulatorArm64TestCompileKlibraries,iosSimulatorArm64TestCompileOnlyDependenciesMetadata,iosSimulatorArm64TestImplementationDependenciesMetadata,iosSimulatorArm64TestResolvableDependenciesMetadata,iosTestApiDependenciesMetadata,iosTestCompileOnlyDependenciesMetadata,iosTestImplementationDependenciesMetadata,iosTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,linuxArm64TestApiDependenciesMetadata,linuxArm64TestCInterop,linuxArm64TestCompilationDependenciesMetadata,linuxArm64TestCompileKlibraries,linuxArm64TestCompileOnlyDependenciesMetadata,linuxArm64TestImplementationDependenciesMetadata,linuxArm64TestResolvableDependenciesMetadata,linuxTestApiDependenciesMetadata,linuxTestCompileOnlyDependenciesMetadata,linuxTestImplementationDependenciesMetadata,linuxTestResolvableDependenciesMetadata,linuxX64TestApiDependenciesMetadata,linuxX64TestCInterop,linuxX64TestCompilationDependenciesMetadata,linuxX64TestCompileKlibraries,linuxX64TestCompileOnlyDependenciesMetadata,linuxX64TestImplementationDependenciesMetadata,linuxX64TestResolvableDependenciesMetadata,macosArm64TestApiDependenciesMetadata,macosArm64TestCInterop,macosArm64TestCompilationDependenciesMetadata,macosArm64TestCompileKlibraries,macosArm64TestCompileOnlyDependenciesMetadata,macosArm64TestImplementationDependenciesMetadata,macosArm64TestResolvableDependenciesMetadata,macosTestApiDependenciesMetadata,macosTestCompileOnlyDependenciesMetadata,macosTestImplementationDependenciesMetadata,macosTestResolvableDependenciesMetadata,macosX64TestApiDependenciesMetadata,macosX64TestCInterop,macosX64TestCompilationDependenciesMetadata,macosX64TestCompileKlibraries,macosX64TestCompileOnlyDependenciesMetadata,macosX64TestImplementationDependenciesMetadata,macosX64TestResolvableDependenciesMetadata,mingwTestApiDependenciesMetadata,mingwTestCompileOnlyDependenciesMetadata,mingwTestImplementationDependenciesMetadata,mingwTestResolvableDependenciesMetadata,mingwX64TestApiDependenciesMetadata,mingwX64TestCInterop,mingwX64TestCompilationDependenciesMetadata,mingwX64TestCompileKlibraries,mingwX64TestCompileOnlyDependenciesMetadata,mingwX64TestImplementationDependenciesMetadata,mingwX64TestResolvableDependenciesMetadata,nativeTestApiDependenciesMetadata,nativeTestCompileOnlyDependenciesMetadata,nativeTestImplementationDependenciesMetadata,nativeTestResolvableDependenciesMetadata,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-html-jvm:0.9.1=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains:annotations:13.0=_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-host-retention,_internal-unified-test-platform-android-test-plugin-result-listener-gradle,androidDebugCompileClasspath,androidDebugRuntimeClasspath,androidReleaseCompileClasspath,androidReleaseRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,jvmCompileClasspath,jvmMainCompileClasspath,jvmMainRuntimeClasspath,jvmRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathAndroidDebug,kotlinCompilerPluginClasspathAndroidDebugAndroidTest,kotlinCompilerPluginClasspathAndroidDebugUnitTest,kotlinCompilerPluginClasspathAndroidRelease,kotlinCompilerPluginClasspathAndroidReleaseUnitTest,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataAppleMain,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataIosMain,kotlinCompilerPluginClasspathMetadataLinuxMain,kotlinCompilerPluginClasspathMetadataMacosMain,kotlinCompilerPluginClasspathMetadataMain,kotlinCompilerPluginClasspathMetadataNativeMain,kotlinKlibCommonizerClasspath,releaseCompileClasspath,releaseRuntimeClasspath
+org.jetbrains:annotations:23.0.0=_internal-unified-test-platform-android-device-provider-ddmlib,androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,dokkaHtmlGeneratorRuntimeResolver~internal,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains:markdown-jvm:0.7.3=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jetbrains:markdown:0.7.3=dokkaHtmlGeneratorRuntimeResolver~internal
+org.jsoup:jsoup:1.16.1=dokkaHtmlGeneratorRuntimeResolver~internal
+org.junit.jupiter:junit-jupiter-api:5.8.2=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+org.junit.platform:junit-platform-commons:1.8.2=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+org.junit.platform:junit-platform-engine:1.8.2=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+org.junit.platform:junit-platform-launcher:1.8.2=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+org.junit.platform:junit-platform-suite-api:1.8.2=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+org.junit:junit-bom:5.8.2=jvmTestCompileClasspath,jvmTestRuntimeClasspath
+org.opentest4j:opentest4j:1.3.0=androidDebugAndroidTestCompileClasspath,androidDebugAndroidTestRuntimeClasspath,androidDebugUnitTestCompileClasspath,androidDebugUnitTestRuntimeClasspath,androidReleaseUnitTestCompileClasspath,androidReleaseUnitTestRuntimeClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+empty=androidApis,androidDebugIntransitiveDependenciesMetadata,androidInstrumentedTestDebugIntransitiveDependenciesMetadata,androidInstrumentedTestIntransitiveDependenciesMetadata,androidJdkImage,androidMainIntransitiveDependenciesMetadata,androidReleaseIntransitiveDependenciesMetadata,androidTestUtil,androidUnitTestDebugIntransitiveDependenciesMetadata,androidUnitTestIntransitiveDependenciesMetadata,androidUnitTestReleaseIntransitiveDependenciesMetadata,appleMainApiDependenciesMetadata,appleMainCInterop,appleMainCompileOnlyDependenciesMetadata,appleMainImplementationDependenciesMetadata,appleMainIntransitiveDependenciesMetadata,appleMainResolvableDependenciesMetadata,appleTestIntransitiveDependenciesMetadata,commonMainIntransitiveDependenciesMetadata,commonTestIntransitiveDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,dokkaHtmlModuleOutputDirectoriesResolver~internal,dokkaHtmlPublicationPluginResolver~internal,iosArm64MainApiDependenciesMetadata,iosArm64MainCompileOnlyDependenciesMetadata,iosArm64MainImplementationDependenciesMetadata,iosArm64MainIntransitiveDependenciesMetadata,iosArm64MainResolvableDependenciesMetadata,iosArm64TestIntransitiveDependenciesMetadata,iosMainApiDependenciesMetadata,iosMainCInterop,iosMainCompileOnlyDependenciesMetadata,iosMainImplementationDependenciesMetadata,iosMainIntransitiveDependenciesMetadata,iosMainResolvableDependenciesMetadata,iosSimulatorArm64MainApiDependenciesMetadata,iosSimulatorArm64MainCompileOnlyDependenciesMetadata,iosSimulatorArm64MainImplementationDependenciesMetadata,iosSimulatorArm64MainIntransitiveDependenciesMetadata,iosSimulatorArm64MainResolvableDependenciesMetadata,iosSimulatorArm64TestIntransitiveDependenciesMetadata,iosTestIntransitiveDependenciesMetadata,jvmMainAnnotationProcessor,jvmMainIntransitiveDependenciesMetadata,jvmTestAnnotationProcessor,jvmTestIntransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,lintChecks,lintPublish,linuxArm64MainApiDependenciesMetadata,linuxArm64MainCompileOnlyDependenciesMetadata,linuxArm64MainImplementationDependenciesMetadata,linuxArm64MainIntransitiveDependenciesMetadata,linuxArm64MainResolvableDependenciesMetadata,linuxArm64TestIntransitiveDependenciesMetadata,linuxMainApiDependenciesMetadata,linuxMainCInterop,linuxMainCompileOnlyDependenciesMetadata,linuxMainImplementationDependenciesMetadata,linuxMainIntransitiveDependenciesMetadata,linuxMainResolvableDependenciesMetadata,linuxTestIntransitiveDependenciesMetadata,linuxX64MainApiDependenciesMetadata,linuxX64MainCompileOnlyDependenciesMetadata,linuxX64MainImplementationDependenciesMetadata,linuxX64MainIntransitiveDependenciesMetadata,linuxX64MainResolvableDependenciesMetadata,linuxX64TestIntransitiveDependenciesMetadata,macosArm64MainApiDependenciesMetadata,macosArm64MainCompileOnlyDependenciesMetadata,macosArm64MainImplementationDependenciesMetadata,macosArm64MainIntransitiveDependenciesMetadata,macosArm64MainResolvableDependenciesMetadata,macosArm64TestIntransitiveDependenciesMetadata,macosMainApiDependenciesMetadata,macosMainCInterop,macosMainCompileOnlyDependenciesMetadata,macosMainImplementationDependenciesMetadata,macosMainIntransitiveDependenciesMetadata,macosMainResolvableDependenciesMetadata,macosTestIntransitiveDependenciesMetadata,macosX64MainApiDependenciesMetadata,macosX64MainCompileOnlyDependenciesMetadata,macosX64MainImplementationDependenciesMetadata,macosX64MainIntransitiveDependenciesMetadata,macosX64MainResolvableDependenciesMetadata,macosX64TestIntransitiveDependenciesMetadata,mingwMainApiDependenciesMetadata,mingwMainCompileOnlyDependenciesMetadata,mingwMainImplementationDependenciesMetadata,mingwMainIntransitiveDependenciesMetadata,mingwMainResolvableDependenciesMetadata,mingwTestIntransitiveDependenciesMetadata,mingwX64MainApiDependenciesMetadata,mingwX64MainCompileOnlyDependenciesMetadata,mingwX64MainImplementationDependenciesMetadata,mingwX64MainIntransitiveDependenciesMetadata,mingwX64MainResolvableDependenciesMetadata,mingwX64TestIntransitiveDependenciesMetadata,nativeMainApiDependenciesMetadata,nativeMainCInterop,nativeMainCompileOnlyDependenciesMetadata,nativeMainImplementationDependenciesMetadata,nativeMainIntransitiveDependenciesMetadata,nativeMainResolvableDependenciesMetadata,nativeTestIntransitiveDependenciesMetadata,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,resolvableIosArm64CompilationApi,resolvableIosArm64TestCompilationApi,resolvableIosSimulatorArm64CompilationApi,resolvableIosSimulatorArm64TestCompilationApi,resolvableLinuxArm64CompilationApi,resolvableLinuxArm64TestCompilationApi,resolvableLinuxX64CompilationApi,resolvableLinuxX64TestCompilationApi,resolvableMacosArm64CompilationApi,resolvableMacosArm64TestCompilationApi,resolvableMacosX64CompilationApi,resolvableMacosX64TestCompilationApi,resolvableMingwX64CompilationApi,resolvableMingwX64TestCompilationApi,testKotlinScriptDefExtensions
diff --git a/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt b/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt
index 80672c8..289e2d7 100644
--- a/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt
+++ b/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt
@@ -2,9 +2,9 @@ package io.github.treesitter.ktreesitter
import br.com.colman.kotest.KotestRunnerAndroid
import io.github.treesitter.ktreesitter.java.TreeSitterJava
-import io.kotest.assertions.throwables.shouldNotThrowAny
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.*
+import io.kotest.matchers.collections.shouldBeEmpty
import io.kotest.matchers.comparables.*
import io.kotest.matchers.nulls.*
import io.kotest.matchers.string.*
@@ -15,8 +15,8 @@ import org.junit.runner.RunWith
class LanguageTest : FunSpec({
val language = Language(TreeSitterJava.language())
- test("version") {
- language.version shouldBe 14U
+ test("abiVersion") {
+ language.abiVersion shouldBe 14U
}
test("symbolCount") {
@@ -31,6 +31,19 @@ class LanguageTest : FunSpec({
language.fieldCount shouldBeGreaterThan 1U
}
+ test("name") {
+ language.name.shouldBeNull()
+ }
+
+ test("metadata") {
+ language.metadata.shouldBeNull()
+ }
+
+ @OptIn(ExperimentalUnsignedTypes::class)
+ test("supertypes") {
+ language.supertypes.shouldBeEmpty()
+ }
+
test("symbolName()") {
language.symbolName(1U) shouldBe "identifier"
}
@@ -40,6 +53,11 @@ class LanguageTest : FunSpec({
language.symbolForName("program", true) shouldBeGreaterThan 0U
}
+ @OptIn(ExperimentalUnsignedTypes::class)
+ test("subtypes") {
+ language.subtypes(1U).shouldBeEmpty()
+ }
+
test("isNamed()") {
language.isNamed(1U) shouldBe true
}
@@ -72,10 +90,6 @@ class LanguageTest : FunSpec({
lookahead.language shouldBe language
}
- test("query()") {
- shouldNotThrowAny { language.query("(program) @root") }
- }
-
test("equals()") {
Language(TreeSitterJava.language()) shouldBe language.copy()
}
@@ -85,6 +99,6 @@ class LanguageTest : FunSpec({
}
test("toString()") {
- language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, version=14\)""")
+ language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, abiVersion=14\)""")
}
})
diff --git a/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt b/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt
index dbcd3bc..f08e1a5 100644
--- a/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt
+++ b/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt
@@ -149,6 +149,14 @@ class NodeTest : FunSpec({
shouldThrow { rootNode.namedChild(1U) }
}
+ test("firstChildForByte()") {
+ rootNode.firstChildForByte(10U)!!.type shouldBe "class_declaration"
+ }
+
+ test("firstNamedChildForByte()") {
+ rootNode.firstNamedChildForByte(10U)!!.type shouldBe "class_declaration"
+ }
+
test("childByFieldId()") {
rootNode.childByFieldId(0U).shouldBeNull()
}
@@ -177,13 +185,6 @@ class NodeTest : FunSpec({
rootNode.child(0U)!!.fieldNameForNamedChild(2U).shouldBeNull()
}
- @Suppress("DEPRECATION")
- test("childContainingDescendant()") {
- val descendant = rootNode.child(0U)!!.child(0U)!!
- val child = rootNode.childContainingDescendant(descendant)
- child?.type shouldBe "class_declaration"
- }
-
test("childWithDescendant()") {
val descendant = rootNode.child(0U)!!
val child = rootNode.childWithDescendant(descendant)
diff --git a/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt b/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt
index 995c139..ce4cf34 100644
--- a/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt
+++ b/ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt
@@ -30,12 +30,6 @@ class ParserTest : FunSpec({
parser.includedRanges shouldHaveSingleElement range
}
- test("timeoutMicros") {
- parser.timeoutMicros shouldBe 0UL
- parser.timeoutMicros = 10000UL
- parser.timeoutMicros shouldBe 10000UL
- }
-
test("logger") {
shouldNotThrowAnyUnit {
parser.logger = { _, _ ->
@@ -61,12 +55,12 @@ class ParserTest : FunSpec({
}
// UTF-16
- source = "var java = \"💩\""
- tree = parser.parse(source)
- tree.text()?.subSequence(12, 14) shouldBe "\uD83D\uDCA9"
+ source = "\uFEFFvar java = \"💩\""
+ tree = parser.parse(source, encoding = InputEncoding.UTF_16BE)
+ tree.text()?.subSequence(13, 15) shouldBe "\uD83D\uDCA9"
}
- test("parse(callback)") {
+ test("parse(readCallback)") {
val source = "class Foo {}"
val tree = parser.parse { byte, _ ->
val end = minOf(byte.toInt() * 2, source.length)
@@ -77,9 +71,8 @@ class ParserTest : FunSpec({
}
afterTest { (test, _) ->
- when (test.name.testName) {
+ when (test.name.name) {
"includedRanges" -> parser.includedRanges = emptyList()
- "timeoutMicros" -> parser.timeoutMicros = 0UL
"logger" -> parser.logger = null
}
}
diff --git a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt
new file mode 100644
index 0000000..f927ec4
--- /dev/null
+++ b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt
@@ -0,0 +1,14 @@
+package io.github.treesitter.ktreesitter
+
+import java.nio.charset.Charset
+
+/**
+ * The encoding of the input text.
+ *
+ * @since 0.25.0
+ */
+actual enum class InputEncoding(val charset: Charset) {
+ UTF_8(Charsets.UTF_8),
+ UTF_16LE(Charsets.UTF_16LE),
+ UTF_16BE(Charsets.UTF_16BE)
+}
diff --git a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Language.kt b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
index 4000182..2147011 100644
--- a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
+++ b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
@@ -6,12 +6,13 @@ import dalvik.annotation.optimization.FastNative
/**
* A class that defines how to parse a particular language.
*
- * When a [Language] is generated by the Tree-sitter CLI, it is assigned
- * an ABI [version] number that corresponds to the current CLI version.
+ * When a [Language] is generated by the Tree-sitter CLI, it is assigned an
+ * [ABI version][abiVersion] number that corresponds to the current CLI version.
*
* @constructor Create a new instance from the given language pointer.
* @param language A pointer to a `TSLanguage` cast to [Long].
- * @throws [IllegalArgumentException] If the pointer is invalid or the [version] is incompatible.
+ * @throws [IllegalArgumentException]
+ * If the pointer is invalid or the [version][abiVersion] is incompatible.
*/
actual class Language @Throws(IllegalArgumentException::class) actual constructor(language: Any) {
@JvmField
@@ -22,7 +23,17 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
checkVersion()
}
+ /**
+ * The ABI version number for this language.
+ *
+ * @since 0.25.0
+ */
+ @get:JvmName("getAbiVersion")
+ actual val abiVersion: UInt
+ @FastNative external get
+
/** The ABI version number for this language. */
+ @Deprecated("version is deprecated", ReplaceWith("abiVersion"), DeprecationLevel.ERROR)
@get:JvmName("getVersion")
actual val version: UInt
@FastNative external get
@@ -42,6 +53,32 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
actual val fieldCount: UInt
@FastNative external get
+ /**
+ * The name of the language, if available.
+ *
+ * @since 0.25.0
+ */
+ actual val name: String?
+ @FastNative external get
+
+ /**
+ * The metadata of the language, if available.
+ *
+ * @since 0.25.0
+ */
+ actual val metadata: Metadata?
+ @FastNative external get
+
+ /**
+ * The supertype symbols of the language.
+ *
+ * @since 0.25.0
+ */
+ @OptIn(ExperimentalUnsignedTypes::class)
+ @get:JvmName("getSupertypes")
+ actual val supertypes: UShortArray
+ @FastNative external get
+
/**
* Get another reference to the language.
*
@@ -59,6 +96,17 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
@JvmName("symbolForName")
actual external fun symbolForName(name: String, isNamed: Boolean): UShort
+ /**
+ * Get the subtype symbols for the given supertype symbol
+ *
+ * @since 0.25.0
+ * @see supertypes
+ */
+ @FastNative
+ @JvmName("subtypes")
+ @OptIn(ExperimentalUnsignedTypes::class)
+ actual external fun subtypes(supertype: UShort): UShortArray
+
/**
* Check if the node for the given numerical ID is named
*
@@ -119,11 +167,12 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
/**
* Create a new [Query] from a string containing one or more S-expression
- * [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax).
+ * [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html).
*
* @throws [QueryError] If any error occurred while creating the query.
*/
@Throws(QueryError::class)
+ @Deprecated("Use the Query constructor instead")
actual fun query(source: String) = Query(this, source)
actual override fun equals(other: Any?) =
@@ -131,12 +180,33 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
actual override fun hashCode() = self.hashCode()
- override fun toString() = "Language(id=0x${self.toString(16)}, version=$version)"
+ override fun toString() = "Language(id=0x${self.toString(16)}, abiVersion=$abiVersion)"
@FastNative
@Throws(IllegalArgumentException::class)
private external fun checkVersion()
+ /**
+ * A class containing the [Language] metadata.
+ *
+ * @property semanticVersion The [Semantic Version](https://semver.org/) of the [Language].
+ */
+ @ConsistentCopyVisibility
+ actual data class Metadata internal actual constructor(
+ @get:JvmName("getSemanticVersion")
+ actual val semanticVersion: Triple
+ ) {
+ actual override fun toString() = buildString {
+ append("Metadata(semanticVersion=\"")
+ append(semanticVersion.first)
+ append('.')
+ append(semanticVersion.second)
+ append('.')
+ append(semanticVersion.third)
+ append("\")")
+ }
+ }
+
private companion object {
@JvmStatic
@CriticalNative
diff --git a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
index afa9dfc..59c34f1 100644
--- a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
+++ b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
@@ -80,7 +80,7 @@ actual class LookaheadIterator @Throws(IllegalArgumentException::class) internal
override fun close() = delete(self)
- override fun computeNext() = if (nativeNext()) {
+ actual override fun computeNext() = if (nativeNext()) {
setNext(Symbol(currentSymbol, currentSymbolName))
} else {
done()
diff --git a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Node.kt b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
index fe7f81a..8608780 100644
--- a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
+++ b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
@@ -207,6 +207,26 @@ actual class Node internal constructor(
@Throws(IndexOutOfBoundsException::class)
actual external fun namedChild(index: UInt): Node?
+ /**
+ * Get the node's first child that contains
+ * or starts after the given byte offset.
+ *
+ * @since 0.25.0
+ */
+ @FastNative
+ @JvmName("firstChildForByte")
+ actual external fun firstChildForByte(byte: UInt): Node?
+
+ /**
+ * Get the node's first _named_ child that contains
+ * or starts after the given byte offset.
+ *
+ * @since 0.25.0
+ */
+ @FastNative
+ @JvmName("firstNamedChildForByte")
+ actual external fun firstNamedChildForByte(byte: UInt): Node?
+
/**
* Get the node's child with the given field ID, if any.
*
@@ -249,14 +269,6 @@ actual class Node internal constructor(
@Throws(IndexOutOfBoundsException::class)
actual external fun fieldNameForNamedChild(index: UInt): String?
- /** Get the child of the node that contains the given descendant, if any. */
- @FastNative
- @Deprecated(
- "This method will not return a direct descendant",
- ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
- )
- actual external fun childContainingDescendant(descendant: Node): Node?
-
/**
* Get the node that contains the given descendant, if any.
*
diff --git a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
index 9cf1b3f..54de309 100644
--- a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
+++ b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
@@ -50,6 +50,7 @@ actual class Parser actual constructor() : AutoCloseable {
*/
@get:JvmName("getTimeoutMicros")
@set:JvmName("setTimeoutMicros")
+ @Deprecated("Use the progressCallback in parse()")
actual var timeoutMicros: ULong
@FastNative external get
@@ -82,11 +83,10 @@ actual class Parser actual constructor() : AutoCloseable {
* [Tree.edit] method in a way that exactly matches the source code changes.
*
* @throws [IllegalStateException]
- * If the parser does not have a [language] assigned or
- * if parsing was cancelled due to a [timeout][timeoutMicros].
+ * If the parser does not have a [language] assigned or if parsing was halted.
*/
@Throws(IllegalStateException::class)
- actual external fun parse(source: String, oldTree: Tree?): Tree
+ actual external fun parse(source: String, encoding: InputEncoding, oldTree: Tree?): Tree
/**
* Parse source code from a callback and create a syntax tree.
@@ -98,19 +98,22 @@ actual class Parser actual constructor() : AutoCloseable {
* [Tree.edit] method in a way that exactly matches the source code changes.
*
* @throws [IllegalStateException]
- * If the parser does not have a [language] assigned or
- * if parsing was cancelled due to a [timeout][timeoutMicros].
+ * If the parser does not have a [language] assigned or if parsing was halted.
*/
@Throws(IllegalStateException::class)
- actual external fun parse(oldTree: Tree?, callback: ParseCallback): Tree
+ actual external fun parse(
+ encoding: InputEncoding,
+ oldTree: Tree?,
+ progressCallback: ParseProgressCallback?,
+ readCallback: ParseReadCallback
+ ): Tree
/**
* Instruct the parser to start the next [parse] from the beginning.
*
- * If the parser previously failed because of a [timeout][timeoutMicros],
- * then by default, it will resume where it left off. If you don't
- * want to resume, and instead intend to use this parser to parse
- * some other document, you must call this method first.
+ * If parsing was previously halted, then by default, it will resume where
+ * it left off. If you don't want to resume, and instead intend to use this
+ * parser to parse some other document, you must call this method first.
*/
@FastNative
actual external fun reset()
diff --git a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Query.kt b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
index 2a1d173..b63dacc 100644
--- a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
+++ b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
@@ -18,13 +18,9 @@ actual class Query @Throws(QueryError::class) actual constructor(
private val language: Language,
private val source: String
) : AutoCloseable {
- private val self: Long = init(language.self, source)
+ internal val self: Long = init(language.self, source)
- private val cursor: Long = cursor()
-
- private val captureNames: MutableList
-
- private val predicates: List>
+ internal val predicates: List>
private val settingList: List>
@@ -33,25 +29,40 @@ actual class Query @Throws(QueryError::class) actual constructor(
/** The number of patterns in the query. */
@get:JvmName("getPatternCount")
actual val patternCount: UInt
- @FastNative external get
+ get() = nativePatternCount().toUInt()
/** The number of captures in the query. */
@get:JvmName("getCaptureCount")
+ @Deprecated("captureCount is deprecated.", ReplaceWith("captureNames.size"))
actual val captureCount: UInt
- @FastNative external get
+ get() = nativeCaptureCount().toUInt()
+
+ /**
+ * The capture names used in the query.
+ *
+ * @since 0.25.0
+ */
+ actual val captureNames: List
+
+ /**
+ * The string literals used in the query.
+ *
+ * @since 0.25.0
+ */
+ actual val stringValues: List
init {
- RefCleaner(this, CleanAction(self, cursor))
+ RefCleaner(this, CleanAction(self))
- predicates = List(patternCount.toInt()) { mutableListOf() }
- settingList = List(patternCount.toInt()) { mutableMapOf() }
- assertionList = List(patternCount.toInt()) { mutableMapOf() }
- captureNames = MutableList(captureCount.toInt()) {
+ predicates = List(nativePatternCount()) { mutableListOf() }
+ settingList = List(nativePatternCount()) { mutableMapOf() }
+ assertionList = List(nativePatternCount()) { mutableMapOf() }
+ captureNames = List(nativeCaptureCount()) {
checkNotNull(captureNameForId(it)) {
"Failed to get capture name at index $it"
}
}
- val stringValues = List(stringCount()) {
+ stringValues = List(stringCount()) {
checkNotNull(stringValueForId(it)) {
"Failed to get string value at index $it"
}
@@ -268,134 +279,15 @@ actual class Query @Throws(QueryError::class) actual constructor(
}
/**
- * The maximum duration in microseconds that query
- * execution should be allowed to take before halting.
- *
- * Default: `0`
- *
- * @since 0.23.0
- */
- @get:JvmName("getTimeoutMicros")
- @set:JvmName("setTimeoutMicros")
- actual var timeoutMicros: ULong
- @FastNative external get
-
- @FastNative external set
-
- /**
- * The maximum number of in-progress matches.
- *
- * Default: `UInt.MAX_VALUE`
- *
- * @throws [IllegalArgumentException] If the match limit is set to `0`.
- */
- @get:JvmName("getMatchLimit")
- @set:JvmName("setMatchLimit")
- actual var matchLimit: UInt
- @FastNative external get
-
- @FastNative external set
-
- /**
- * The maximum start depth for the query.
- *
- * This prevents cursors from exploring children nodes at a certain depth.
- * Note that if a pattern includes many children, then they will still be checked.
- *
- * Default: `UInt.MAX_VALUE`
- */
- @get:JvmName("getMaxStartDepth")
- @set:JvmName("setMaxStartDepth")
- actual var maxStartDepth: UInt = UInt.MAX_VALUE
- @FastNative external set
-
- /**
- * The range of bytes in which the query will be executed.
- *
- * Default: `UInt.MIN_VALUE..UInt.MAX_VALUE`
- */
- actual var byteRange: UIntRange = UInt.MIN_VALUE..UInt.MAX_VALUE
- set(value) {
- nativeSetByteRange(value.first.toInt(), value.last.toInt())
- field = value
- }
-
- /**
- * The range of points in which the query will be executed.
- *
- * Default: `Point.MIN..Point.MAX`
- */
- actual var pointRange: ClosedRange = Point.MIN..Point.MAX
- set(value) {
- nativeSetPointRange(value.start, value.endInclusive)
- field = value
- }
-
- /**
- * Check if the query exceeded its maximum number of
- * in-progress matches during its last execution.
- */
- @get:JvmName("didExceedMatchLimit")
- actual val didExceedMatchLimit: Boolean
- @FastNative external get
-
- /**
- * Iterate over all the matches in the order that they were found.
- *
- * #### Example
- *
- * ```kotlin
- * query.matches(tree.rootNode) {
- * if (name != "ieq?") return@matches true
- * val node = it[(args[0] as QueryPredicateArg.Capture).value].first()
- * val value = (args[1] as QueryPredicateArg.Literal).value
- * value.equals(node.text()?.toString(), ignoreCase = true)
- * }
- * ```
- *
- * @param node The node that the query will run on.
- * @param predicate A function that handles custom predicates.
- */
- @JvmOverloads
- actual fun matches(
- node: Node,
- predicate: QueryPredicate.(QueryMatch) -> Boolean
- ): Sequence {
- exec(node)
- return sequence {
- var match = nextMatch(node.tree)
- while (match != null) {
- val result = match.check(node.tree, predicate)
- if (result != null) yield(result)
- match = nextMatch(node.tree)
- }
- }
- }
-
- /**
- * Iterate over all the individual captures in the order that they appear.
+ * Execute the query on the given [Node].
*
- * This is useful if you don't care about _which_ pattern matched.
- *
- * @param node The node that the query will run on.
- * @param predicate A function that handles custom predicates.
+ * @since 0.25.0
*/
+ @FastNative
@JvmOverloads
- actual fun captures(
- node: Node,
- predicate: QueryPredicate.(QueryMatch) -> Boolean
- ): Sequence> {
- exec(node)
- return sequence {
- var capture = nextCapture(node.tree)
- while (capture != null) {
- val index = capture.first
- val match = capture.second.check(node.tree, predicate)
- if (match != null) yield(index to match)
- capture = nextCapture(node.tree)
- }
- }
- }
+ @JvmName("exec")
+ actual operator fun invoke(node: Node, progressCallback: QueryProgressCallback?) =
+ QueryCursor(this, node, progressCallback)
/**
* Get the property settings for the given pattern index.
@@ -410,7 +302,7 @@ actual class Query @Throws(QueryError::class) actual constructor(
@Throws(IndexOutOfBoundsException::class)
actual fun settings(index: UInt): Map {
if (index >= patternCount)
- throw IndexOutOfBoundsException("Pattern index $index is out of bounds")
+ throw IndexOutOfBoundsException("Index $index exceeds count $patternCount")
return settingList[index]
}
@@ -429,7 +321,7 @@ actual class Query @Throws(QueryError::class) actual constructor(
@Throws(IndexOutOfBoundsException::class)
actual fun assertions(index: UInt): Map> {
if (index >= patternCount)
- throw IndexOutOfBoundsException("Pattern index $index is out of bounds")
+ throw IndexOutOfBoundsException("Index $index exceeds count $patternCount")
return assertionList[index]
}
@@ -453,15 +345,9 @@ actual class Query @Throws(QueryError::class) actual constructor(
* This prevents the capture from being returned in matches,
* and also avoids most resource usage associated with recording
* the capture. Currently, there is no way to undo this.
- *
- * @throws [NoSuchElementException] If the capture does not exist.
*/
- @Throws(NoSuchElementException::class)
- actual fun disableCapture(name: String) {
- if (!captureNames.remove(name))
- throw NoSuchElementException("Capture @$name does not exist")
- nativeDisableCapture(name)
- }
+ @FastNative
+ actual external fun disableCapture(name: String)
/**
* Get the byte offset where the given pattern starts in the query's source.
@@ -517,7 +403,6 @@ actual class Query @Throws(QueryError::class) actual constructor(
* Check if a pattern is guaranteed to match
* once a given byte offset is reached.
*/
- @FastNative
@JvmName("isPatternGuaranteedAtStep")
@Throws(IndexOutOfBoundsException::class)
actual fun isPatternGuaranteedAtStep(offset: UInt): Boolean {
@@ -528,17 +413,16 @@ actual class Query @Throws(QueryError::class) actual constructor(
override fun toString() = "Query(language=$language, source=$source)"
- override fun close() = delete(self, cursor)
+ override fun close() = delete(self)
@FastNative
- private external fun stringCount(): Int
+ private external fun nativePatternCount(): Int
@FastNative
- private external fun exec(node: Node)
-
- private external fun nextMatch(tree: Tree): QueryMatch?
+ private external fun nativeCaptureCount(): Int
- private external fun nextCapture(tree: Tree): Pair?
+ @FastNative
+ private external fun stringCount(): Int
@FastNative
private external fun captureNameForId(index: Int): String?
@@ -546,31 +430,11 @@ actual class Query @Throws(QueryError::class) actual constructor(
@FastNative
private external fun stringValueForId(index: Int): String?
- @FastNative
- private external fun nativeSetByteRange(start: Int, end: Int)
-
- @FastNative
- private external fun nativeSetPointRange(start: Point, end: Point)
-
- @FastNative
- private external fun nativeDisableCapture(name: String)
-
@FastNative
private external fun nativeIsPatternGuaranteedAtStep(index: Int): Boolean
private external fun predicatesForPattern(index: Int): List?
- private inline fun QueryMatch.check(
- tree: Tree,
- predicate: QueryPredicate.(QueryMatch) -> Boolean
- ): QueryMatch? {
- if (tree.text() == null) return this
- val result = predicates[patternIndex].all {
- if (it !is QueryPredicate.Generic) it(this) else predicate(it, this)
- }
- return if (result) this else null
- }
-
@Suppress("NOTHING_TO_INLINE")
private inline operator fun List.get(index: UInt) = get(index.toInt())
@@ -580,8 +444,8 @@ actual class Query @Throws(QueryError::class) actual constructor(
private inline val IntArray.type: Int
inline get() = get(1)
- private class CleanAction(private val query: Long, private val cursor: Long) : Runnable {
- override fun run() = delete(query, cursor)
+ private class CleanAction(private val ptr: Long) : Runnable {
+ override fun run() = delete(ptr)
}
@Suppress("ConstPropertyName")
@@ -598,10 +462,6 @@ actual class Query @Throws(QueryError::class) actual constructor(
@JvmStatic
@CriticalNative
- private external fun cursor(): Long
-
- @JvmStatic
- @CriticalNative
- private external fun delete(query: Long, cursor: Long)
+ private external fun delete(self: Long)
}
}
diff --git a/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt
new file mode 100644
index 0000000..4a24ccd
--- /dev/null
+++ b/ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt
@@ -0,0 +1,209 @@
+package io.github.treesitter.ktreesitter
+
+import dalvik.annotation.optimization.CriticalNative
+import dalvik.annotation.optimization.FastNative
+
+/**
+ * A class that is used for executing a query.
+ *
+ * __NOTE:__ If you're targeting Android SDK level < 33,
+ * you must `use` or [close] the instance to free up resources.
+ *
+ * @since 0.25.0
+ */
+actual class QueryCursor internal constructor(
+ private val query: Query,
+ private val node: Node,
+ progressCallback: QueryProgressCallback? = null
+) : AutoCloseable {
+ private val self: Long = init()
+
+ init {
+ RefCleaner(this, CleanAction(self))
+
+ exec(query.self, node, progressCallback)
+ }
+
+ /**
+ * The maximum duration in microseconds that query
+ * execution should be allowed to take before halting.
+ *
+ * Default: `0`
+ *
+ * @since 0.23.0
+ */
+ @get:JvmName("getTimeoutMicros")
+ @set:JvmName("setTimeoutMicros")
+ @Deprecated("Use the progressCallback in Query.invoke()")
+ actual var timeoutMicros: ULong
+ @FastNative external get
+
+ @FastNative external set
+
+ /**
+ * The maximum number of in-progress matches.
+ *
+ * Default: `UInt.MAX_VALUE`
+ *
+ * @throws [IllegalArgumentException] If the match limit is set to `0`.
+ */
+ @get:JvmName("getMatchLimit")
+ @set:JvmName("setMatchLimit")
+ @set:Throws(IllegalArgumentException::class)
+ actual var matchLimit: UInt
+ @FastNative external get
+
+ @FastNative external set
+
+ /**
+ * The maximum start depth for the query.
+ *
+ * This prevents cursors from exploring children nodes at a certain depth.
+ * Note that if a pattern includes many children, then they will still be checked.
+ *
+ * Default: `UInt.MAX_VALUE`
+ */
+ @get:JvmName("getMaxStartDepth")
+ @set:JvmName("setMaxStartDepth")
+ actual var maxStartDepth: UInt = UInt.MAX_VALUE
+ @FastNative external set
+
+ /**
+ * The range of bytes in which the query will be executed.
+ *
+ * The query cursor will return matches that intersect with
+ * the given range. This means that a match may be returned
+ * even if some of its captures fall outside the specified range,
+ * as long as at least part of the match overlaps with the range.
+ *
+ * Default: `UInt.MIN_VALUE..UInt.MAX_VALUE`
+ *
+ * @throws [IllegalArgumentException] If set to an invalid range.
+ */
+ actual var byteRange: UIntRange = UInt.MIN_VALUE..UInt.MAX_VALUE
+ set(value) {
+ require(nativeSetByteRange(value.first.toInt(), value.last.toInt())) {
+ "Invalid byte range: [${value.first}, ${value.last}]"
+ }
+ field = value
+ }
+
+ /**
+ * The range of points in which the query will be executed.
+ *
+ * The query cursor will return matches that intersect with
+ * the given range. This means that a match may be returned
+ * even if some of its captures fall outside the specified range,
+ * as long as at least part of the match overlaps with the range.
+ *
+ * Default: `Point.MIN..Point.MAX`
+ */
+ actual var pointRange: ClosedRange = Point.MIN..Point.MAX
+ set(value) {
+ require(nativeSetPointRange(value.start, value.endInclusive)) {
+ "Invalid point range: [${value.start}, ${value.endInclusive}]"
+ }
+ field = value
+ }
+
+ /**
+ * Check if the query exceeded its maximum number of
+ * in-progress matches during its last execution.
+ *
+ * @see matchLimit
+ */
+ @get:JvmName("didExceedMatchLimit")
+ actual val didExceedMatchLimit: Boolean
+ @FastNative external get
+
+ /**
+ * Iterate over all the matches in the order that they were found.
+ *
+ * #### Example
+ *
+ * ```kotlin
+ * query(tree.rootNode).matches {
+ * if (name != "ieq?") return@matches true
+ * val node = it[(args[0] as QueryPredicateArg.Capture).value].first()
+ * val value = (args[1] as QueryPredicateArg.Literal).value
+ * value.equals(node.text()?.toString(), ignoreCase = true)
+ * }
+ * ```
+ *
+ * @param predicate A function that handles custom predicates.
+ */
+ @JvmOverloads
+ actual fun matches(predicate: QueryPredicate.(QueryMatch) -> Boolean) = sequence {
+ var match = nextMatch(query.captureNames, node.tree)
+ while (match != null) {
+ val result = match.check(predicate)
+ if (result != null) yield(result)
+ match = nextMatch(query.captureNames, node.tree)
+ }
+ }
+
+ /**
+ * Iterate over all the individual captures in the order that they appear.
+ *
+ * This is useful if you don't care about _which_ pattern matched.
+ *
+ * @param predicate A function that handles custom predicates.
+ */
+ @JvmOverloads
+ actual fun captures(predicate: QueryPredicate.(QueryMatch) -> Boolean) =
+ sequence> {
+ var capture = nextCapture(query.captureNames, node.tree)
+ while (capture != null) {
+ val index = capture.first
+ val match = capture.second.check(predicate)
+ if (match != null) yield(index to match)
+ capture = nextCapture(query.captureNames, node.tree)
+ }
+ }
+
+ override fun toString() = "QueryCursor(query=$query, node=$node)"
+
+ override fun close() = delete(self)
+
+ @FastNative
+ private external fun nativeSetByteRange(start: Int, end: Int): Boolean
+
+ @FastNative
+ private external fun nativeSetPointRange(start: Point, end: Point): Boolean
+
+ @FastNative
+ private external fun nextMatch(captureNames: List, tree: Tree): QueryMatch?
+
+ @FastNative
+ private external fun nextCapture(
+ captureNames: List,
+ tree: Tree
+ ): Pair?
+
+ @FastNative
+ private external fun exec(query: Long, node: Node, progressCallback: QueryProgressCallback?)
+
+ private inline fun QueryMatch.check(
+ predicate: QueryPredicate.(QueryMatch) -> Boolean
+ ): QueryMatch? {
+ if (node.tree.text() == null) return this
+ val result = query.predicates[patternIndex.toInt()].all {
+ if (it !is QueryPredicate.Generic) it(this) else predicate(it, this)
+ }
+ return if (result) this else null
+ }
+
+ private class CleanAction(private val ptr: Long) : Runnable {
+ override fun run() = delete(ptr)
+ }
+
+ private companion object {
+ @JvmStatic
+ @CriticalNative
+ private external fun init(): Long
+
+ @JvmStatic
+ @CriticalNative
+ private external fun delete(self: Long)
+ }
+}
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt
new file mode 100644
index 0000000..4733b06
--- /dev/null
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt
@@ -0,0 +1,8 @@
+package io.github.treesitter.ktreesitter
+
+/**
+ * The encoding of the input text.
+ *
+ * @since 0.25.0
+ */
+expect enum class InputEncoding { UTF_8, UTF_16LE, UTF_16BE }
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Language.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
index 297e6f7..19ca63c 100644
--- a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
@@ -10,7 +10,15 @@ package io.github.treesitter.ktreesitter
* @throws [IllegalArgumentException] If the pointer is invalid or the [version] is incompatible.
*/
expect class Language @Throws(IllegalArgumentException::class) constructor(language: Any) {
+ /**
+ * The ABI version number for this language.
+ *
+ * @since 0.25.0
+ */
+ val abiVersion: UInt
+
/** The ABI version number for this language. */
+ @Deprecated("version is deprecated", ReplaceWith("abiVersion"), DeprecationLevel.ERROR)
val version: UInt
/** The number of distinct node types in this language. */
@@ -22,6 +30,28 @@ expect class Language @Throws(IllegalArgumentException::class) constructor(langu
/** The number of distinct field names in this language. */
val fieldCount: UInt
+ /**
+ * The name of the language, if available.
+ *
+ * @since 0.25.0
+ */
+ val name: String?
+
+ /**
+ * The metadata of the language, if available.
+ *
+ * @since 0.25.0
+ */
+ val metadata: Metadata?
+
+ /**
+ * The supertype symbols of the language.
+ *
+ * @since 0.25.0
+ */
+ @OptIn(ExperimentalUnsignedTypes::class)
+ val supertypes: UShortArray
+
/**
* Get another reference to the language.
*
@@ -35,6 +65,15 @@ expect class Language @Throws(IllegalArgumentException::class) constructor(langu
/** Get the numerical ID for the given node type. */
fun symbolForName(name: String, isNamed: Boolean): UShort
+ /**
+ * Get the subtype symbols for the given supertype symbol
+ *
+ * @since 0.25.0
+ * @see supertypes
+ */
+ @OptIn(ExperimentalUnsignedTypes::class)
+ fun subtypes(supertype: UShort): UShortArray
+
/**
* Check if the node for the given numerical ID is named
*
@@ -82,14 +121,26 @@ expect class Language @Throws(IllegalArgumentException::class) constructor(langu
/**
* Create a new [Query] from a string containing one or more S-expression
- * [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax).
+ * [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html).
*
* @throws [QueryError] If any error occurred while creating the query.
*/
@Throws(QueryError::class)
+ @Deprecated("Use the Query constructor instead")
fun query(source: String): Query
override fun equals(other: Any?): Boolean
override fun hashCode(): Int
+
+ /**
+ * A class containing the [Language] metadata.
+ *
+ * @property semanticVersion The [Semantic Version](https://semver.org/) of the [Language].
+ */
+ class Metadata internal constructor(semanticVersion: Triple) {
+ val semanticVersion: Triple
+
+ override fun toString(): String
+ }
}
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
index 46bb316..58b7339 100644
--- a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
@@ -42,6 +42,8 @@ expect class LookaheadIterator : AbstractIterator {
/** Iterate over the symbol names. */
fun symbolNames(): Sequence
+ override fun computeNext()
+
/** A class that pairs a symbol ID with its name. */
class Symbol(id: UShort, name: String) {
val id: UShort
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Node.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
index e1f1d3a..f8f37d4 100644
--- a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
@@ -154,6 +154,22 @@ expect class Node {
@Throws(IndexOutOfBoundsException::class)
fun namedChild(index: UInt): Node?
+ /**
+ * Get the node's first child that contains
+ * or starts after the given byte offset.
+ *
+ * @since 0.25.0
+ */
+ fun firstChildForByte(byte: UInt): Node?
+
+ /**
+ * Get the node's first _named_ child that contains
+ * or starts after the given byte offset.
+ *
+ * @since 0.25.0
+ */
+ fun firstNamedChildForByte(byte: UInt): Node?
+
/**
* Get the node's child with the given field ID, if any.
*
@@ -187,13 +203,6 @@ expect class Node {
@Throws(IndexOutOfBoundsException::class)
fun fieldNameForNamedChild(index: UInt): String?
- /** Get the child of the node that contains the given descendant, if any. */
- @Deprecated(
- "This method will not return a direct descendant",
- ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
- )
- fun childContainingDescendant(descendant: Node): Node?
-
/**
* Get the node that contains the given descendant, if any.
*
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
index 02bf659..5b87bb9 100644
--- a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
@@ -5,7 +5,19 @@ package io.github.treesitter.ktreesitter
*
* The function should return `null` to indicate the end of the document.
*/
-typealias ParseCallback = (byte: UInt, point: Point) -> CharSequence?
+typealias ParseReadCallback = (byte: UInt, point: Point) -> CharSequence?
+
+/**
+ * A function that is called during parsing.
+ *
+ * The first argument contains the current byte offset and the second
+ * argument indicates whether the parser has encountered an error.
+ *
+ * If the function returns `false`, parsing will halt early.
+ *
+ * @since 0.25.0
+ */
+typealias ParseProgressCallback = (currentByteOffset: UInt, hasError: Boolean) -> Boolean
/**
* A function that logs parsing results.
@@ -45,14 +57,13 @@ expect class Parser() {
* The maximum duration in microseconds that parsing
* should be allowed to take before halting.
*/
+ @Deprecated("Use the progressCallback in parse()")
var timeoutMicros: ULong
/** The logger that the parser will use during parsing. */
@get:Deprecated("The logger can't be called directly.", level = DeprecationLevel.HIDDEN)
var logger: LogFunction?
- // TODO: add cancellationFlag
-
/**
* Parse a source code string and create a syntax tree.
*
@@ -63,11 +74,14 @@ expect class Parser() {
* [Tree.edit] method in a way that exactly matches the source code changes.
*
* @throws [IllegalStateException]
- * If the parser does not have a [language] assigned or
- * if parsing was cancelled due to a [timeout][timeoutMicros].
+ * If the parser does not have a [language] assigned or if parsing was halted.
*/
@Throws(IllegalStateException::class)
- fun parse(source: String, oldTree: Tree? = null): Tree
+ fun parse(
+ source: String,
+ encoding: InputEncoding = InputEncoding.UTF_8,
+ oldTree: Tree? = null
+ ): Tree
/**
* Parse source code from a callback and create a syntax tree.
@@ -79,19 +93,22 @@ expect class Parser() {
* [Tree.edit] method in a way that exactly matches the source code changes.
*
* @throws [IllegalStateException]
- * If the parser does not have a [language] assigned or
- * if parsing was cancelled due to a [timeout][timeoutMicros].
+ * If the parser does not have a [language] assigned or if parsing was halted.
*/
@Throws(IllegalStateException::class)
- fun parse(oldTree: Tree? = null, callback: ParseCallback): Tree
+ fun parse(
+ encoding: InputEncoding = InputEncoding.UTF_8,
+ oldTree: Tree? = null,
+ progressCallback: ParseProgressCallback? = null,
+ readCallback: ParseReadCallback
+ ): Tree
/**
* Instruct the parser to start the next [parse] from the beginning.
*
- * If the parser previously failed because of a [timeout][timeoutMicros],
- * then by default, it will resume where it left off. If you don't
- * want to resume, and instead intend to use this parser to parse
- * some other document, you must call this method first.
+ * If parsing was previously halted, then by default, it will resume where
+ * it left off. If you don't want to resume, and instead intend to use this
+ * parser to parse some other document, you must call this method first.
*/
fun reset()
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Query.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
index e6e7e25..9c739ee 100644
--- a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
@@ -1,5 +1,16 @@
package io.github.treesitter.ktreesitter
+/**
+ * A function that is called while executing a query.
+ *
+ * The argument contains the current byte offset.
+ *
+ * If the function returns `false`, the execution will halt early.
+ *
+ * @since 0.25.0
+ */
+typealias QueryProgressCallback = (currentByteOffset: UInt) -> Boolean
+
/**
* A class that represents a set of patterns which match nodes in a syntax tree.
*
@@ -13,91 +24,29 @@ expect class Query @Throws(QueryError::class) constructor(language: Language, so
val patternCount: UInt
/** The number of captures in the query. */
+ @Deprecated("captureCount is deprecated.", ReplaceWith("captureNames.size"))
val captureCount: UInt
/**
- * The maximum duration in microseconds that query
- * execution should be allowed to take before halting.
- *
- * Default: `0`
+ * The capture names used in the query.
*
- * @since 0.23.0
+ * @since 0.25.0
*/
- var timeoutMicros: ULong
+ val captureNames: List
/**
- * The maximum number of in-progress matches.
- *
- * Default: `UInt.MAX_VALUE`
+ * The string literals used in the query.
*
- * @throws [IllegalArgumentException] If the match limit is set to `0`.
+ * @since 0.25.0
*/
- var matchLimit: UInt
+ val stringValues: List
/**
- * The maximum start depth for the query.
+ * Execute the query on the given [Node].
*
- * This prevents cursors from exploring children nodes at a certain depth.
- * Note that if a pattern includes many children, then they will still be checked.
- *
- * Default: `UInt.MAX_VALUE`
- */
- var maxStartDepth: UInt
-
- /**
- * The range of bytes in which the query will be executed.
- *
- * Default: `UInt.MIN_VALUE..UInt.MAX_VALUE`
+ * @since 0.25.0
*/
- var byteRange: UIntRange
-
- /**
- * The range of points in which the query will be executed.
- *
- * Default: `Point.MIN..Point.MAX`
- */
- var pointRange: ClosedRange
-
- /**
- * Check if the query exceeded its maximum number of
- * in-progress matches during its last execution.
- */
- val didExceedMatchLimit: Boolean
-
- /**
- * Iterate over all the matches in the order that they were found.
- *
- * #### Example
- *
- * ```kotlin
- * query.matches(tree.rootNode) {
- * if (name != "ieq?") return@matches true
- * val node = it[(args[0] as QueryPredicateArg.Capture).value].first()
- * val value = (args[1] as QueryPredicateArg.Literal).value
- * value.equals(node.text()?.toString(), ignoreCase = true)
- * }
- * ```
- *
- * @param node The node that the query will run on.
- * @param predicate A function that handles custom predicates.
- */
- fun matches(
- node: Node,
- predicate: QueryPredicate.(QueryMatch) -> Boolean = { true }
- ): Sequence
-
- /**
- * Iterate over all the individual captures in the order that they appear.
- *
- * This is useful if you don't care about _which_ pattern matched.
- *
- * @param node The node that the query will run on.
- * @param predicate A function that handles custom predicates.
- */
- fun captures(
- node: Node,
- predicate: QueryPredicate.(QueryMatch) -> Boolean = { true }
- ): Sequence>
+ operator fun invoke(node: Node, progressCallback: QueryProgressCallback? = null): QueryCursor
/**
* Get the property settings for the given pattern index.
@@ -142,10 +91,7 @@ expect class Query @Throws(QueryError::class) constructor(language: Language, so
* This prevents the capture from being returned in matches,
* and also avoids most resource usage associated with recording
* the capture. Currently, there is no way to undo this.
- *
- * @throws [NoSuchElementException] If the capture does not exist.
*/
- @Throws(NoSuchElementException::class)
fun disableCapture(name: String)
/**
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/QueryCapture.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/QueryCapture.kt
index a11578f..fb618ac 100644
--- a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/QueryCapture.kt
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/QueryCapture.kt
@@ -8,6 +8,7 @@ import kotlin.jvm.JvmName
* @property node The captured node.
* @property name The name of the capture.
*/
+@ConsistentCopyVisibility
data class QueryCapture internal constructor(
@get:JvmName("node") val node: Node,
@get:JvmName("name") val name: String
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt
new file mode 100644
index 0000000..9b80910
--- /dev/null
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt
@@ -0,0 +1,103 @@
+package io.github.treesitter.ktreesitter
+
+/**
+ * A class that is used for executing a query.
+ *
+ * @since 0.25.0
+ */
+expect class QueryCursor {
+ /**
+ * The maximum duration in microseconds that query
+ * execution should be allowed to take before halting.
+ *
+ * Default: `0`
+ *
+ * @since 0.23.0
+ */
+ @Deprecated("Use the progressCallback in Query.invoke()")
+ var timeoutMicros: ULong
+
+ /**
+ * The maximum number of in-progress matches.
+ *
+ * Default: `UInt.MAX_VALUE`
+ *
+ * @throws [IllegalArgumentException] If the match limit is set to `0`.
+ */
+ var matchLimit: UInt
+
+ /**
+ * The maximum start depth for the query.
+ *
+ * This prevents cursors from exploring children nodes at a certain depth.
+ * Note that if a pattern includes many children, then they will still be checked.
+ *
+ * Default: `UInt.MAX_VALUE`
+ */
+ var maxStartDepth: UInt
+
+ /**
+ * The range of bytes in which the query will be executed.
+ *
+ * The query cursor will return matches that intersect with
+ * the given range. This means that a match may be returned
+ * even if some of its captures fall outside the specified range,
+ * as long as at least part of the match overlaps with the range.
+ *
+ * Default: `UInt.MIN_VALUE..UInt.MAX_VALUE`
+ *
+ * @throws [IllegalArgumentException] If set to an invalid range.
+ */
+ var byteRange: UIntRange
+
+ /**
+ * The range of points in which the query will be executed.
+ *
+ * The query cursor will return matches that intersect with
+ * the given range. This means that a match may be returned
+ * even if some of its captures fall outside the specified range,
+ * as long as at least part of the match overlaps with the range.
+ *
+ * Default: `Point.MIN..Point.MAX`
+ *
+ * @throws [IllegalArgumentException] If set to an invalid range.
+ */
+ var pointRange: ClosedRange
+
+ /**
+ * Check if the cursor exceeded its maximum number of
+ * in-progress matches during its last execution.
+ *
+ * @see matchLimit
+ */
+ val didExceedMatchLimit: Boolean
+
+ /**
+ * Iterate over all the matches in the order that they were found.
+ *
+ * #### Example
+ *
+ * ```kotlin
+ * query(tree.rootNode).matches {
+ * if (name != "ieq?") return@matches true
+ * val node = it[(args[0] as QueryPredicateArg.Capture).value].first()
+ * val value = (args[1] as QueryPredicateArg.Literal).value
+ * value.equals(node.text()?.toString(), ignoreCase = true)
+ * }
+ * ```
+ *
+ * @param predicate A function that handles custom predicates.
+ */
+ fun matches(predicate: QueryPredicate.(QueryMatch) -> Boolean = { true }): Sequence
+
+ /**
+ * Iterate over all the individual captures in the order that they appear.
+ *
+ * This is useful if you don't care about _which_ pattern matched.
+ *
+ * @param predicate A function that handles custom predicates.
+ */
+ fun captures(
+ predicate: QueryPredicate.(QueryMatch) -> Boolean = { true }
+ ): Sequence>
+}
diff --git a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Range.kt b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Range.kt
index 5df68b3..281494e 100644
--- a/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Range.kt
+++ b/ktreesitter/src/commonMain/kotlin/io/github/treesitter/ktreesitter/Range.kt
@@ -18,7 +18,7 @@ data class Range @Throws(IllegalArgumentException::class) constructor(
@get:JvmName("endByte") val endByte: UInt
) {
init {
- require(startPoint <= endPoint) { "Invalid point range: $startPoint to $endPoint" }
- require(startByte <= endByte) { "Invalid byte range: $startByte to $endByte" }
+ require(startPoint <= endPoint) { "Invalid point range: [$startPoint, $endPoint]" }
+ require(startByte <= endByte) { "Invalid byte range: [$startByte, $endByte]" }
}
}
diff --git a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt
index dd36a8a..f98a076 100644
--- a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt
+++ b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt
@@ -1,9 +1,9 @@
package io.github.treesitter.ktreesitter
import io.github.treesitter.ktreesitter.java.TreeSitterJava
-import io.kotest.assertions.throwables.shouldNotThrowAny
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.*
+import io.kotest.matchers.collections.shouldBeEmpty
import io.kotest.matchers.comparables.*
import io.kotest.matchers.nulls.*
import io.kotest.matchers.string.*
@@ -12,8 +12,8 @@ import io.kotest.matchers.types.*
class LanguageTest : FunSpec({
val language = Language(TreeSitterJava.language())
- test("version") {
- language.version shouldBe 14U
+ test("abiVersion") {
+ language.abiVersion shouldBe 14U
}
test("symbolCount") {
@@ -28,6 +28,19 @@ class LanguageTest : FunSpec({
language.fieldCount shouldBeGreaterThan 1U
}
+ test("name") {
+ language.name.shouldBeNull()
+ }
+
+ test("metadata") {
+ language.metadata.shouldBeNull()
+ }
+
+ @OptIn(ExperimentalUnsignedTypes::class)
+ test("supertypes") {
+ language.supertypes.shouldBeEmpty()
+ }
+
test("symbolName()") {
language.symbolName(1U) shouldBe "identifier"
}
@@ -37,6 +50,11 @@ class LanguageTest : FunSpec({
language.symbolForName("program", true) shouldBeGreaterThan 0U
}
+ @OptIn(ExperimentalUnsignedTypes::class)
+ test("subtypes") {
+ language.subtypes(1U).shouldBeEmpty()
+ }
+
test("isNamed()") {
language.isNamed(1U) shouldBe true
}
@@ -69,10 +87,6 @@ class LanguageTest : FunSpec({
lookahead.language shouldBe language
}
- test("query()") {
- shouldNotThrowAny { language.query("(program) @root") }
- }
-
test("equals()") {
Language(TreeSitterJava.language()) shouldBe language.copy()
}
@@ -82,6 +96,6 @@ class LanguageTest : FunSpec({
}
test("toString()") {
- language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, version=14\)""")
+ language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, abiVersion=14\)""")
}
})
diff --git a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt
index e866bc5..01a401d 100644
--- a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt
+++ b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt
@@ -146,6 +146,14 @@ class NodeTest : FunSpec({
shouldThrow { rootNode.namedChild(1U) }
}
+ test("firstChildForByte()") {
+ rootNode.firstChildForByte(10U)!!.type shouldBe "class_declaration"
+ }
+
+ test("firstNamedChildForByte()") {
+ rootNode.firstNamedChildForByte(10U)!!.type shouldBe "class_declaration"
+ }
+
test("childByFieldId()") {
rootNode.childByFieldId(0U).shouldBeNull()
}
@@ -174,13 +182,6 @@ class NodeTest : FunSpec({
rootNode.child(0U)!!.fieldNameForNamedChild(2U).shouldBeNull()
}
- @Suppress("DEPRECATION")
- test("childContainingDescendant()") {
- val descendant = rootNode.child(0U)!!.child(0U)!!
- val child = rootNode.childContainingDescendant(descendant)
- child?.type shouldBe "class_declaration"
- }
-
test("childWithDescendant()") {
val descendant = rootNode.child(0U)!!
val child = rootNode.childWithDescendant(descendant)
diff --git a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt
index 4d668fb..777f5b4 100644
--- a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt
+++ b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt
@@ -27,12 +27,6 @@ class ParserTest : FunSpec({
parser.includedRanges shouldHaveSingleElement range
}
- test("timeoutMicros") {
- parser.timeoutMicros shouldBe 0UL
- parser.timeoutMicros = 10000UL
- parser.timeoutMicros shouldBe 10000UL
- }
-
test("logger") {
shouldNotThrowAnyUnit {
parser.logger = { _, _ ->
@@ -58,12 +52,12 @@ class ParserTest : FunSpec({
}
// UTF-16
- source = "var java = \"💩\""
- tree = parser.parse(source)
- tree.text()?.subSequence(12, 14) shouldBe "\uD83D\uDCA9"
+ source = "\uFEFFvar java = \"💩\""
+ tree = parser.parse(source, encoding = InputEncoding.UTF_16BE)
+ tree.text()?.subSequence(13, 15) shouldBe "\uD83D\uDCA9"
}
- test("parse(callback)") {
+ test("parse(readCallback)") {
val source = "class Foo {}"
val tree = parser.parse { byte, _ ->
val end = minOf(byte.toInt() * 2, source.length)
@@ -74,9 +68,8 @@ class ParserTest : FunSpec({
}
afterTest { (test, _) ->
- when (test.name.testName) {
+ when (test.name.name) {
"includedRanges" -> parser.includedRanges = emptyList()
- "timeoutMicros" -> parser.timeoutMicros = 0UL
"logger" -> parser.logger = null
}
}
diff --git a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/QueryCursorTest.kt b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/QueryCursorTest.kt
new file mode 100644
index 0000000..dae039c
--- /dev/null
+++ b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/QueryCursorTest.kt
@@ -0,0 +1,160 @@
+package io.github.treesitter.ktreesitter
+
+import io.github.treesitter.ktreesitter.java.TreeSitterJava
+import io.kotest.core.spec.style.FunSpec
+import io.kotest.inspectors.forAll
+import io.kotest.inspectors.forSingle
+import io.kotest.matchers.*
+import io.kotest.matchers.collections.*
+
+class QueryCursorTest :
+ FunSpec({
+ val language = Language(TreeSitterJava.language())
+ val parser = Parser(language)
+ val source = """
+ (identifier) @identifier
+
+ (class_declaration
+ name: (identifier) @class
+ (class_body) @body)
+ """.trimIndent()
+ val query = Query(language, source)
+ val tree = parser.parse("class Foo {}")
+
+ @Suppress("DEPRECATION")
+ test("timeoutMicros") {
+ val cursor = query(tree.rootNode)
+ cursor.timeoutMicros shouldBe 0UL
+ cursor.timeoutMicros = 10UL
+ cursor.timeoutMicros shouldBe 10UL
+ }
+
+ test("matchLimit") {
+ val cursor = query(tree.rootNode)
+ cursor.matchLimit shouldBe UInt.MAX_VALUE
+ cursor.matchLimit = 10U
+ cursor.matchLimit shouldBe 10U
+ }
+
+ test("maxStartDepth") {
+ val cursor = query(tree.rootNode)
+ cursor.maxStartDepth = 10U
+ cursor.maxStartDepth shouldBe 10U
+ }
+
+ test("byteRange") {
+ val cursor = query(tree.rootNode)
+ cursor.byteRange = 0U..10U
+ cursor.byteRange.last shouldBe 10U
+ }
+
+ test("pointRange") {
+ val cursor = query(tree.rootNode)
+ cursor.pointRange = Point(0U, 10U)..Point.MAX
+ cursor.pointRange.start shouldBe Point(0U, 10U)
+ }
+
+ test("didExceedMatchLimit") {
+ val cursor = query(tree.rootNode)
+ cursor.didExceedMatchLimit shouldBe false
+ }
+
+ test("matches()") {
+ var cursor = query(tree.rootNode)
+ var matches = cursor.matches().toList()
+ matches.shouldHaveSize(2).shouldBeMonotonicallyIncreasingWith { a, b ->
+ a.patternIndex.compareTo(b.patternIndex)
+ }
+
+ var tree = parser.parse("int y = x + 1;")
+ var query = Query(
+ language,
+ """
+ ((variable_declarator
+ (identifier) @y
+ (binary_expression
+ (identifier) @x))
+ (#not-eq? @y @x))
+ """.trimIndent()
+ )
+ cursor = query(tree.rootNode)
+ matches = cursor.matches().toList()
+ matches.forSingle {
+ it.captures[0].node.text() shouldBe "y"
+ }
+
+ tree = parser.parse(
+ """
+ class Foo {}
+ class Bar {}
+ """.trimIndent()
+ )
+ query = Query(
+ language,
+ """
+ ((identifier) @foo
+ (#eq? @foo "Foo"))
+ """.trimIndent()
+ )
+ cursor = query(tree.rootNode)
+ matches = cursor.matches().toList()
+ matches.forSingle {
+ it.captures[0].node.text() shouldBe "Foo"
+ }
+
+ query = Query(
+ language,
+ """
+ ((identifier) @name
+ (#not-any-of? @name "Foo" "Bar"))
+ """.trimIndent()
+ )
+ cursor = query(tree.rootNode)
+ matches = cursor.matches().toList()
+ matches.shouldBeEmpty()
+
+ query = Query(
+ language,
+ """
+ ((identifier) @foo
+ (#ieq? @foo "foo"))
+ """.trimIndent()
+ )
+ cursor = query(tree.rootNode)
+ matches = cursor.matches {
+ if (name != "ieq?") return@matches true
+ val node = it[(args[0] as QueryPredicateArg.Capture).value].single()
+ (args[1] as QueryPredicateArg.Literal).value.equals(node.text().toString(), true)
+ }.toList()
+ matches.forSingle {
+ it.captures[0].node.text() shouldBe "Foo"
+ }
+ }
+
+ test("captures()") {
+ var cursor = query(tree.rootNode)
+ var captures = cursor.captures().toList()
+ captures.shouldHaveSize(3).take(2).forAll {
+ it.second.captures[0].node.type shouldBe "identifier"
+ }
+
+ var tree = parser.parse(
+ """
+ /// foo
+ /// bar
+ """.trimIndent()
+ )
+ var query = Query(
+ language,
+ """
+ ((line_comment)+ @foo
+ (#any-match? @foo "foo"))
+ """.trimIndent()
+ )
+ cursor = query(tree.rootNode)
+ captures = cursor.captures().toList()
+ captures.shouldHaveSize(2).forAll {
+ it.second.captures[0].name shouldBe "foo"
+ }
+ }
+ })
diff --git a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/QueryTest.kt b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/QueryTest.kt
index 18a509e..15c7092 100644
--- a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/QueryTest.kt
+++ b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/QueryTest.kt
@@ -5,16 +5,12 @@ import io.kotest.assertions.throwables.shouldNotThrowAny
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.assertions.throwables.shouldThrowWithMessage
import io.kotest.core.spec.style.FunSpec
-import io.kotest.inspectors.forAll
import io.kotest.inspectors.forOne
-import io.kotest.inspectors.forSingle
import io.kotest.matchers.*
-import io.kotest.matchers.collections.*
class QueryTest :
FunSpec({
val language = Language(TreeSitterJava.language())
- val parser = Parser(language)
val source = """
(identifier) @identifier
@@ -65,144 +61,6 @@ class QueryTest :
query.patternCount shouldBe 2U
}
- test("captureCount") {
- val query = Query(language, source)
- query.captureCount shouldBe 3U
- }
-
- test("timeoutMicros") {
- val query = Query(language, source)
- query.timeoutMicros shouldBe 0UL
- query.timeoutMicros = 10UL
- query.timeoutMicros shouldBe 10UL
- }
-
- test("matchLimit") {
- val query = Query(language, source)
- query.matchLimit shouldBe UInt.MAX_VALUE
- query.matchLimit = 10U
- query.matchLimit shouldBe 10U
- }
-
- test("maxStartDepth") {
- val query = Query(language, source)
- query.maxStartDepth = 10U
- query.maxStartDepth shouldBe 10U
- }
-
- test("byteRange") {
- val query = Query(language, source)
- query.byteRange = 0U..10U
- query.byteRange.last shouldBe 10U
- }
-
- test("pointRange") {
- val query = Query(language, source)
- query.pointRange = Point(0U, 10U)..Point.MAX
- query.pointRange.start shouldBe Point(0U, 10U)
- }
-
- test("didExceedMatchLimit") {
- val query = Query(language, source)
- query.didExceedMatchLimit shouldBe false
- }
-
- test("matches()") {
- var tree = parser.parse("class Foo {}")
- var query = Query(language, source)
- var matches = query.matches(tree.rootNode).toList()
- matches.shouldHaveSize(2).shouldBeMonotonicallyIncreasingWith { a, b ->
- a.patternIndex.compareTo(b.patternIndex)
- }
-
- tree = parser.parse("int y = x + 1;")
- query = Query(
- language,
- """
- ((variable_declarator
- (identifier) @y
- (binary_expression
- (identifier) @x))
- (#not-eq? @y @x))
- """.trimIndent()
- )
- matches = query.matches(tree.rootNode).toList()
- matches.forSingle {
- it.captures[0].node.text() shouldBe "y"
- }
-
- tree = parser.parse(
- """
- class Foo {}
- class Bar {}
- """.trimIndent()
- )
- query = Query(
- language,
- """
- ((identifier) @foo
- (#eq? @foo "Foo"))
- """.trimIndent()
- )
- matches = query.matches(tree.rootNode).toList()
- matches.forSingle {
- it.captures[0].node.text() shouldBe "Foo"
- }
-
- query = Query(
- language,
- """
- ((identifier) @name
- (#not-any-of? @name "Foo" "Bar"))
- """.trimIndent()
- )
- matches = query.matches(tree.rootNode).toList()
- matches.shouldBeEmpty()
-
- query = Query(
- language,
- """
- ((identifier) @foo
- (#ieq? @foo "foo"))
- """.trimIndent()
- )
- matches = query.matches(tree.rootNode) {
- if (name != "ieq?") return@matches true
- val node = it[(args[0] as QueryPredicateArg.Capture).value].single()
- (args[1] as QueryPredicateArg.Literal).value.equals(node.text().toString(), true)
- }.toList()
- matches.forSingle {
- it.captures[0].node.text() shouldBe "Foo"
- }
- }
-
- test("captures()") {
- var tree = parser.parse("class Foo {}")
- var query = Query(language, source)
- var captures = query.captures(tree.rootNode).toList()
- captures.shouldHaveSize(3).take(2).forAll {
- it.second.captures[0].node.type shouldBe "identifier"
- }
-
- tree = parser.parse(
- """
- /// foo
- /// bar
- """.trimIndent()
- )
- query = Query(
- language,
- """
- ((line_comment)+ @foo
- (#any-match? @foo "foo"))
- """.trimIndent()
- )
- captures = query.captures(tree.rootNode).toList()
- captures.shouldHaveSize(2).forAll {
- it.second.captures[0].name shouldBe "foo"
- }
- }
-
test("settings()") {
var query = Query(
language,
@@ -267,34 +125,6 @@ class QueryTest :
}
}
- test("disablePattern()") {
- val query = Query(language, source)
- query.disablePattern(1U)
- val tree = parser.parse("class Foo {}")
- val matches = query.captures(tree.rootNode).toList()
- matches.forSingle {
- it.second.captures[0].node.type shouldBe "identifier"
- }
-
- shouldThrow {
- query.disablePattern(2U)
- }
- }
-
- test("disableCapture()") {
- val query = Query(language, source)
- query.disableCapture("body")
- val tree = parser.parse("class Foo {}")
- val matches = query.captures(tree.rootNode).toList()
- matches.shouldHaveSize(2).forAll {
- it.second.captures[0].node.type shouldBe "identifier"
- }
-
- shouldThrow {
- query.disableCapture("none")
- }
- }
-
test("startByteForPattern()") {
val query = Query(language, source)
query.startByteForPattern(1U) shouldBe 26U
diff --git a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/TreeTest.kt b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/TreeTest.kt
index 43cac43..4d7aeda 100644
--- a/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/TreeTest.kt
+++ b/ktreesitter/src/commonTest/kotlin/io/github/treesitter/ktreesitter/TreeTest.kt
@@ -41,7 +41,7 @@ class TreeTest : FunSpec({
source = "class Foo2 {}"
tree.edit(edit)
tree.text().shouldBeNull()
- tree = parser.parse(source, tree)
+ tree = parser.parse(source, oldTree = tree)
tree.text() shouldBe source
}
@@ -53,7 +53,7 @@ class TreeTest : FunSpec({
test("changedRanges()") {
val edit = InputEdit(0U, 0U, 7U, Point(0U, 0U), Point(0U, 0U), Point(0U, 7U))
tree.edit(edit)
- val newTree = parser.parse("public $source", tree)
+ val newTree = parser.parse("public $source", oldTree = tree)
tree.changedRanges(newTree).shouldHaveSingleElement {
it.endByte == 7U && it.endPoint.column == 7U
}
diff --git a/ktreesitter/src/jni/language.c b/ktreesitter/src/jni/language.c
index bc57e17..9783ff9 100644
--- a/ktreesitter/src/jni/language.c
+++ b/ktreesitter/src/jni/language.c
@@ -4,9 +4,14 @@ jlong JNICALL language_copy CRITICAL_ARGS(jlong self) {
return (jlong)ts_language_copy((TSLanguage *)self);
}
+jint JNICALL language_get_abi_version(JNIEnv *env, jobject this) {
+ TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
+ return (jint)ts_language_abi_version(self);
+}
+
jint JNICALL language_get_version(JNIEnv *env, jobject this) {
TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
- return (jint)ts_language_version(self);
+ return (jint)ts_language_abi_version(self);
}
jint JNICALL language_get_symbol_count(JNIEnv *env, jobject this) {
@@ -24,10 +29,46 @@ jint JNICALL language_get_field_count(JNIEnv *env, jobject this) {
return (jint)ts_language_field_count(self);
}
+jstring JNICALL language_get_name(JNIEnv *env, jobject this) {
+ TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
+ const char *name = ts_language_name(self);
+ return name ? (*env)->NewStringUTF(env, name) : NULL;
+}
+
+jobject JNICALL language_get_metadata(JNIEnv *env, jobject this) {
+ TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
+ const TSLanguageMetadata *metadata = ts_language_metadata(self);
+ if (metadata == NULL)
+ return NULL;
+
+ jobject major = (*env)->AllocObject(env, global_class_cache.UShort);
+ (*env)->SetShortField(env, major, global_field_cache.UShort_data,
+ (jshort)metadata->major_version);
+ jobject minor = (*env)->AllocObject(env, global_class_cache.UShort);
+ (*env)->SetShortField(env, minor, global_field_cache.UShort_data,
+ (jshort)metadata->minor_version);
+ jobject patch = (*env)->AllocObject(env, global_class_cache.UShort);
+ (*env)->SetShortField(env, patch, global_field_cache.UShort_data,
+ (jshort)metadata->patch_version);
+ jobject version = NEW_OBJECT(Triple, major, minor, patch);
+ return NEW_OBJECT(Language$Metadata, version);
+}
+
+jshortArray JNICALL language_get_supertypes(JNIEnv *env, jobject this) {
+ TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
+ uint32_t length;
+ const TSSymbol *supertypes = ts_language_supertypes(self, &length);
+ jshortArray result = (*env)->NewShortArray(env, length);
+ if (length > 0) {
+ (*env)->SetShortArrayRegion(env, result, 0, length, (const jshort *)supertypes);
+ }
+ return result;
+}
+
jstring JNICALL language_symbol_name(JNIEnv *env, jobject this, jshort symbol) {
TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
const char *name = ts_language_symbol_name(self, (uint16_t)symbol);
- return (*env)->NewStringUTF(env, name);
+ return name ? (*env)->NewStringUTF(env, name) : NULL;
}
jshort JNICALL language_symbol_for_name(JNIEnv *env, jobject this, jstring name,
@@ -40,6 +81,17 @@ jshort JNICALL language_symbol_for_name(JNIEnv *env, jobject this, jstring name,
return (jshort)symbol;
}
+jshortArray JNICALL language_subtypes(JNIEnv *env, jobject this, jshort supertype) {
+ TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
+ uint32_t length;
+ const TSSymbol *subtypes = ts_language_subtypes(self, supertype, &length);
+ jshortArray result = (*env)->NewShortArray(env, length);
+ if (length > 0) {
+ (*env)->SetShortArrayRegion(env, result, 0, length, (const jshort *)subtypes);
+ }
+ return result;
+}
+
jboolean JNICALL language_is_named(JNIEnv *env, jobject this, jshort symbol) {
TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
TSSymbolType symbol_type = ts_language_symbol_type(self, symbol);
@@ -93,12 +145,17 @@ void JNICALL language_check_version(JNIEnv *env, jobject this) {
const JNINativeMethod Language_methods[] = {
{"copy", "(J)J", (void *)&language_copy},
+ {"getAbiVersion", "()I", (void *)&language_get_abi_version},
{"getVersion", "()I", (void *)&language_get_version},
{"getSymbolCount", "()I", (void *)&language_get_symbol_count},
{"getStateCount", "()I", (void *)&language_get_state_count},
{"getFieldCount", "()I", (void *)&language_get_field_count},
+ {"getName", "()Ljava/lang/String;", (void *)&language_get_name},
+ {"getMetadata", "()L" PACKAGE "Language$Metadata;", (void *)&language_get_metadata},
+ {"getSupertypes", "()[S", (void *)&language_get_supertypes},
{"symbolName", "(S)Ljava/lang/String;", (void *)&language_symbol_name},
{"symbolForName", "(Ljava/lang/String;Z)S", (void *)&language_symbol_for_name},
+ {"subtypes", "(S)[S", (void *)&language_subtypes},
{"isNamed", "(S)Z", (void *)&language_is_named},
{"isVisible", "(S)Z", (void *)&language_is_visible},
{"isSupertype", "(S)Z", (void *)&language_is_supertype},
diff --git a/ktreesitter/src/jni/module.c b/ktreesitter/src/jni/module.c
index 1f5efde..ab67e36 100644
--- a/ktreesitter/src/jni/module.c
+++ b/ktreesitter/src/jni/module.c
@@ -21,6 +21,9 @@ extern const size_t Parser_methods_size;
extern const JNINativeMethod Query_methods[];
extern const size_t Query_methods_size;
+extern const JNINativeMethod QueryCursor_methods[];
+extern const size_t QueryCursor_methods_size;
+
FieldCache global_field_cache = {0};
MethodCache global_method_cache = {0};
ClassCache global_class_cache = {0};
@@ -100,13 +103,15 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *_reserved) {
REGISTER_CLASS(Query);
CACHE_FIELD(Query, self, "J");
- CACHE_FIELD(Query, cursor, "J");
- CACHE_FIELD(Query, matchLimit, "I");
- CACHE_FIELD(Query, maxStartDepth, "I");
CACHE_FIELD(Query, language, "L" PACKAGE "Language;");
- CACHE_FIELD(Query, captureNames, "Ljava/util/List;");
CACHE_FIELD(Query, source, "Ljava/lang/String;");
+ REGISTER_CLASS(QueryCursor);
+ CACHE_FIELD(QueryCursor, self, "J");
+ CACHE_FIELD(QueryCursor, matchLimit, "I");
+ CACHE_FIELD(QueryCursor, maxStartDepth, "I");
+ CACHE_FIELD(QueryCursor, timeoutMicros, "I");
+
REGISTER_CLASS(Parser);
CACHE_FIELD(Parser, self, "J");
CACHE_FIELD(Parser, timeoutMicros, "J");
@@ -134,6 +139,9 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *_reserved) {
CACHE_FIELD(InputEdit, oldEndPoint, "L" PACKAGE "Point;");
CACHE_FIELD(InputEdit, newEndPoint, "L" PACKAGE "Point;");
+ CACHE_CLASS(PACKAGE, Language$Metadata);
+ CACHE_METHOD(Language$Metadata, init, "", "(Lkotlin/Triple;)V");
+
CACHE_CLASS(PACKAGE, QueryCapture);
CACHE_METHOD(QueryCapture, init, "", "(L" PACKAGE "Node;Ljava/lang/String;)V");
@@ -144,6 +152,11 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *_reserved) {
CACHE_STATIC_FIELD(Parser$LogType, LEX, "L" PACKAGE "Parser$LogType;");
CACHE_STATIC_FIELD(Parser$LogType, PARSE, "L" PACKAGE "Parser$LogType;");
+ CACHE_CLASS(PACKAGE, InputEncoding);
+ CACHE_STATIC_FIELD(InputEncoding, UTF_8, "L" PACKAGE "InputEncoding;");
+ CACHE_STATIC_FIELD(InputEncoding, UTF_16LE, "L" PACKAGE "InputEncoding;");
+ CACHE_STATIC_FIELD(InputEncoding, UTF_16BE, "L" PACKAGE "InputEncoding;");
+
CACHE_CLASS(PACKAGE, QueryError$Capture);
CACHE_METHOD(QueryError$Capture, init, "", "(IILjava/lang/String;)V");
@@ -159,6 +172,10 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *_reserved) {
CACHE_CLASS(PACKAGE, QueryError$Structure);
CACHE_METHOD(QueryError$Structure, init, "", "(II)V");
+ CACHE_CLASS("java/lang/", Boolean);
+ CACHE_FIELD(Boolean, value, "Z");
+ CACHE_METHOD(Boolean, init, "", "(Z)V");
+
CACHE_CLASS("java/lang/", CharSequence);
CACHE_METHOD(CharSequence, toString, "toString", "()Ljava/lang/String;");
@@ -173,9 +190,20 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *_reserved) {
CACHE_CLASS("kotlin/", Pair);
CACHE_METHOD(Pair, init, "", "(Ljava/lang/Object;Ljava/lang/Object;)V");
+ CACHE_CLASS("kotlin/", Triple);
+ CACHE_METHOD(Triple, init, "",
+ "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V");
+
CACHE_CLASS("kotlin/", UInt);
CACHE_FIELD(UInt, data, "I");
+ CACHE_CLASS("kotlin/", UShort);
+ CACHE_FIELD(UShort, data, "S");
+
+ CACHE_CLASS("kotlin/jvm/functions/", Function1);
+ CACHE_METHOD(Function2, invoke, "invoke",
+ "(Ljava/lang/Object;)Ljava/lang/Object;");
+
CACHE_CLASS("kotlin/jvm/functions/", Function2);
CACHE_METHOD(Function2, invoke, "invoke",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
@@ -197,12 +225,17 @@ JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *_reserved) {
return;
(*env)->DeleteGlobalRef(env, global_class_cache.ArrayList);
+ (*env)->DeleteGlobalRef(env, global_class_cache.Boolean);
(*env)->DeleteGlobalRef(env, global_class_cache.CharSequence);
+ (*env)->DeleteGlobalRef(env, global_class_cache.Function1);
+ (*env)->DeleteGlobalRef(env, global_class_cache.Function2);
(*env)->DeleteGlobalRef(env, global_class_cache.IllegalArgumentException);
(*env)->DeleteGlobalRef(env, global_class_cache.IllegalStateException);
(*env)->DeleteGlobalRef(env, global_class_cache.IndexOutOfBoundsException);
(*env)->DeleteGlobalRef(env, global_class_cache.InputEdit);
+ (*env)->DeleteGlobalRef(env, global_class_cache.InputEncoding);
(*env)->DeleteGlobalRef(env, global_class_cache.Language);
+ (*env)->DeleteGlobalRef(env, global_class_cache.Language$Metadata);
(*env)->DeleteGlobalRef(env, global_class_cache.List);
(*env)->DeleteGlobalRef(env, global_class_cache.LookaheadIterator);
(*env)->DeleteGlobalRef(env, global_class_cache.Node);
@@ -210,6 +243,7 @@ JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *_reserved) {
(*env)->DeleteGlobalRef(env, global_class_cache.Parser);
(*env)->DeleteGlobalRef(env, global_class_cache.Point);
(*env)->DeleteGlobalRef(env, global_class_cache.Query);
+ (*env)->DeleteGlobalRef(env, global_class_cache.QueryCursor);
(*env)->DeleteGlobalRef(env, global_class_cache.QueryError$Capture);
(*env)->DeleteGlobalRef(env, global_class_cache.QueryError$Field);
(*env)->DeleteGlobalRef(env, global_class_cache.QueryError$NodeType);
@@ -220,5 +254,7 @@ JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *_reserved) {
(*env)->DeleteGlobalRef(env, global_class_cache.Range);
(*env)->DeleteGlobalRef(env, global_class_cache.Tree);
(*env)->DeleteGlobalRef(env, global_class_cache.TreeCursor);
+ (*env)->DeleteGlobalRef(env, global_class_cache.Triple);
(*env)->DeleteGlobalRef(env, global_class_cache.UInt);
+ (*env)->DeleteGlobalRef(env, global_class_cache.UShort);
}
diff --git a/ktreesitter/src/jni/node.c b/ktreesitter/src/jni/node.c
index af42f7e..fef28df 100644
--- a/ktreesitter/src/jni/node.c
+++ b/ktreesitter/src/jni/node.c
@@ -247,6 +247,24 @@ jobject JNICALL node_children_by_field_id(JNIEnv *env, jobject this, jshort id)
return children;
}
+jobject JNICALL node_first_child_for_byte(JNIEnv *env, jobject this, jint byte) {
+ TSNode self = unmarshal_node(env, this);
+ TSNode result = ts_node_first_child_for_byte(self, byte);
+ if (ts_node_is_null(result))
+ return NULL;
+ jobject tree = GET_FIELD(Object, this, Node_tree);
+ return marshal_node(env, result, tree);
+}
+
+jobject JNICALL node_first_named_child_for_byte(JNIEnv *env, jobject this, jint byte) {
+ TSNode self = unmarshal_node(env, this);
+ TSNode result = ts_node_first_named_child_for_byte(self, byte);
+ if (ts_node_is_null(result))
+ return NULL;
+ jobject tree = GET_FIELD(Object, this, Node_tree);
+ return marshal_node(env, result, tree);
+}
+
jstring JNICALL node_field_name_for_child(JNIEnv *env, jobject this, jint index) {
TSNode self = unmarshal_node(env, this);
if (ts_node_child_count(self) <= (uint32_t)index) {
@@ -275,16 +293,6 @@ jstring JNICALL node_field_name_for_named_child(JNIEnv *env, jobject this, jint
return field_name ? (*env)->NewStringUTF(env, field_name) : NULL;
}
-jobject JNICALL node_child_containing_descendant(JNIEnv *env, jobject this, jobject descendant) {
- TSNode self = unmarshal_node(env, this);
- TSNode other = unmarshal_node(env, descendant);
- TSNode result = ts_node_child_containing_descendant(self, other);
- if (ts_node_is_null(result))
- return NULL;
- jobject tree = GET_FIELD(Object, this, Node_tree);
- return marshal_node(env, result, tree);
-}
-
jobject JNICALL node_child_with_descendant(JNIEnv *env, jobject this, jobject descendant) {
TSNode self = unmarshal_node(env, this);
TSNode other = unmarshal_node(env, descendant);
@@ -393,14 +401,14 @@ const JNINativeMethod Node_methods[] = {
{"getChildren", "()Ljava/util/List;", (void *)&node_get_children},
{"child", "(I)L" PACKAGE "Node;", (void *)&node_child},
{"namedChild", "(I)L" PACKAGE "Node;", (void *)&node_named_child},
+ {"firstChildForByte", "(I)L" PACKAGE "Node;", (void *)&node_first_child_for_byte},
+ {"firstNamedChildForByte", "(I)L" PACKAGE "Node;", (void *)&node_first_named_child_for_byte},
{"childByFieldId", "(S)L" PACKAGE "Node;", (void *)&node_child_by_field_id},
{"childByFieldName", "(Ljava/lang/String;)L" PACKAGE "Node;",
(void *)&node_child_by_field_name},
{"childrenByFieldId", "(S)Ljava/util/List;", (void *)&node_children_by_field_id},
{"fieldNameForChild", "(I)Ljava/lang/String;", (void *)&node_field_name_for_child},
{"fieldNameForNamedChild", "(I)Ljava/lang/String;", (void *)&node_field_name_for_named_child},
- {"childContainingDescendant", "(L" PACKAGE "Node;)L" PACKAGE "Node;",
- (void *)&node_child_containing_descendant},
{"childWithDescendant", "(L" PACKAGE "Node;)L" PACKAGE "Node;",
(void *)&node_child_with_descendant},
{"descendant", "(II)L" PACKAGE "Node;", (void *)&node_descendant__bytes},
diff --git a/ktreesitter/src/jni/parser.c b/ktreesitter/src/jni/parser.c
index c40cfdb..d7306b1 100644
--- a/ktreesitter/src/jni/parser.c
+++ b/ktreesitter/src/jni/parser.c
@@ -11,6 +11,22 @@ typedef struct {
} last_result;
} ReadPayload;
+static inline TSInputEncoding get_encoding(JNIEnv *env, jobject encoding) {
+ jobject UTF_8 = GET_STATIC_FIELD(Object, InputEncoding, InputEncoding_UTF_8);
+ if (encoding == NULL || (*env)->IsSameObject(env, encoding, UTF_8)) {
+ return TSInputEncodingUTF8;
+ }
+ jobject UTF_16LE = GET_STATIC_FIELD(Object, InputEncoding, InputEncoding_UTF_16LE);
+ if ((*env)->IsSameObject(env, encoding, UTF_16LE)) {
+ return TSInputEncodingUTF16BE;
+ }
+ jobject UTF_16BE = GET_STATIC_FIELD(Object, InputEncoding, InputEncoding_UTF_16BE);
+ if ((*env)->IsSameObject(env, encoding, UTF_16BE)) {
+ return TSInputEncodingUTF16LE;
+ }
+ UNREACHABLE();
+}
+
static void log_function(void *payload, TSLogType log_type, const char *buffer) {
JNIEnv *env;
int rc = (*java_vm)->GetEnv(java_vm, (void **)&env, JNI_VERSION_1_6);
@@ -38,8 +54,8 @@ static void log_function(void *payload, TSLogType log_type, const char *buffer)
CALL_METHOD(Object, (jobject)payload, Function2_invoke, log_type_value, message);
}
-static const char *parse_callback(void *payload, uint32_t byte_index, TSPoint position,
- uint32_t *bytes_read) {
+static const char *parse_read_callback(void *payload, uint32_t byte_index, TSPoint position,
+ uint32_t *bytes_read) {
ReadPayload *read_payload = (ReadPayload *)payload;
JNIEnv *env = read_payload->env;
jstring last_string = read_payload->last_result.string;
@@ -72,6 +88,20 @@ static const char *parse_callback(void *payload, uint32_t byte_index, TSPoint po
return result;
}
+static bool parse_progress_callback(TSParseState *state) {
+ ProgressPayload *progress_payload = (ProgressPayload *)state->payload;
+ JNIEnv *env = progress_payload->env;
+ jobject offset = (*env)->AllocObject(env, global_class_cache.UInt);
+ (*env)->SetIntField(env, offset, global_field_cache.UInt_data,
+ (jint)state->current_byte_offset);
+ jobject error = NEW_OBJECT(Boolean, (jboolean)state->has_error);
+ jobject result =
+ CALL_METHOD(Object, progress_payload->callback, Function2_invoke, offset, error);
+ (*env)->DeleteLocalRef(env, offset);
+ (*env)->DeleteLocalRef(env, error);
+ return (bool)(*env)->GetBooleanField(env, result, global_field_cache.Boolean_value);
+}
+
jlong JNICALL parser_init CRITICAL_NO_ARGS() { return (jlong)ts_parser_new(); }
void JNICALL parser_delete(JNIEnv *env, jclass _class, jlong self) {
@@ -140,7 +170,8 @@ void JNICALL parser_set_logger(JNIEnv *env, jobject this, jobject value) {
(*env)->SetObjectField(env, this, global_field_cache.Parser_logger, value);
}
-jobject JNICALL parser_parse__string(JNIEnv *env, jobject this, jstring source, jobject old_tree) {
+jobject JNICALL parser_parse__string(JNIEnv *env, jobject this, jstring source, jobject encoding,
+ jobject old_tree) {
TSParser *self = GET_POINTER(TSParser, this, Parser_self);
jobject language = GET_FIELD(Object, this, Parser_language);
if (language == NULL) {
@@ -148,12 +179,14 @@ jobject JNICALL parser_parse__string(JNIEnv *env, jobject this, jstring source,
(*env)->ThrowNew(env, global_class_cache.IllegalStateException, error);
return NULL;
}
- TSTree *old_ts_tree = old_tree ? GET_POINTER(TSTree, old_tree, Tree_self) : NULL;
+ TSTree *old_ts_tree = old_tree ? GET_POINTER(TSTree, old_tree, Tree_self) : NULL;
uint32_t length;
const char *string = (*env)->GetStringUTFChars(env, source, NULL);
length = (uint32_t)(*env)->GetStringUTFLength(env, source);
- TSTree *ts_tree = ts_parser_parse_string(self, old_ts_tree, string, length);
+ TSInputEncoding input_encoding = get_encoding(env, encoding);
+ TSTree *ts_tree =
+ ts_parser_parse_string_encoding(self, old_ts_tree, string, length, input_encoding);
(*env)->ReleaseStringUTFChars(env, source, string);
if (ts_tree == NULL) {
@@ -164,8 +197,9 @@ jobject JNICALL parser_parse__string(JNIEnv *env, jobject this, jstring source,
return NEW_OBJECT(Tree, (jlong)ts_tree, source, language);
}
-jobject JNICALL parser_parse__function(JNIEnv *env, jobject this, jobject old_tree,
- jobject callback) {
+jobject JNICALL parser_parse__function(JNIEnv *env, jobject this, jobject encoding,
+ jobject old_tree, jobject progress_callback,
+ jobject read_callback) {
TSParser *self = GET_POINTER(TSParser, this, Parser_self);
jobject language = GET_FIELD(Object, this, Parser_language);
if (language == NULL) {
@@ -175,13 +209,24 @@ jobject JNICALL parser_parse__function(JNIEnv *env, jobject this, jobject old_tr
}
TSTree *old_ts_tree = old_tree ? GET_POINTER(TSTree, old_tree, Tree_self) : NULL;
- ReadPayload payload = {.env = env, .callback = callback};
+ ReadPayload read_payload = {.env = env, .callback = read_callback};
+ TSInputEncoding input_encoding = get_encoding(env, encoding);
TSInput input = {
- .payload = (void *)&payload,
- .read = parse_callback,
- .encoding = TSInputEncodingUTF8,
+ .payload = (void *)&read_payload,
+ .read = parse_read_callback,
+ .encoding = input_encoding,
};
- TSTree *ts_tree = ts_parser_parse(self, old_ts_tree, input);
+ TSTree *ts_tree;
+ if (progress_callback == NULL) {
+ ts_tree = ts_parser_parse(self, old_ts_tree, input);
+ } else {
+ ProgressPayload progress_payload = {.env = env, .callback = progress_callback};
+ TSParseOptions options = {
+ .payload = (void *)&progress_payload,
+ .progress_callback = parse_progress_callback,
+ };
+ ts_tree = ts_parser_parse_with_options(self, old_ts_tree, input, options);
+ }
if ((*env)->ExceptionCheck(env)) {
(*env)->Throw(env, (*env)->ExceptionOccurred(env));
@@ -208,9 +253,11 @@ const JNINativeMethod Parser_methods[] = {
{"getTimeoutMicros", "()J", (void *)&parser_get_timeout_micros},
{"setTimeoutMicros", "(J)V", (void *)&parser_set_timeout_micros},
{"setLogger", "(Lkotlin/jvm/functions/Function2;)V", (void *)&parser_set_logger},
- {"parse", "(Ljava/lang/String;L" PACKAGE "Tree;)L" PACKAGE "Tree;",
+ {"parse", "(Ljava/lang/String;L" PACKAGE "InputEncoding;L" PACKAGE "Tree;)L" PACKAGE "Tree;",
(void *)&parser_parse__string},
- {"parse", "(L" PACKAGE "Tree;Lkotlin/jvm/functions/Function2;)L" PACKAGE "Tree;",
+ {"parse",
+ "(L" PACKAGE "InputEncoding;L" PACKAGE "Tree;Lkotlin/jvm/functions/Function2;"
+ "Lkotlin/jvm/functions/Function2;)L" PACKAGE "Tree;",
(void *)&parser_parse__function},
{"reset", "()V", (void *)&parser_reset},
};
diff --git a/ktreesitter/src/jni/query.c b/ktreesitter/src/jni/query.c
index 684a4d0..a8b8b03 100644
--- a/ktreesitter/src/jni/query.c
+++ b/ktreesitter/src/jni/query.c
@@ -104,67 +104,21 @@ jlong query_init(JNIEnv *env, jclass _class, jlong language, jstring source) {
return -1;
}
-jlong query_cursor CRITICAL_NO_ARGS() { return (jlong)ts_query_cursor_new(); }
-
void query_delete CRITICAL_ARGS(jlong query, jlong cursor) {
ts_query_delete((TSQuery *)query);
ts_query_cursor_delete((TSQueryCursor *)cursor);
}
-jint query_get_pattern_count(JNIEnv *env, jobject this) {
+jint query_native_pattern_count(JNIEnv *env, jobject this) {
TSQuery *self = GET_POINTER(TSQuery, this, Query_self);
return (jint)ts_query_pattern_count(self);
}
-jint query_get_capture_count(JNIEnv *env, jobject this) {
+jint query_native_capture_count(JNIEnv *env, jobject this) {
TSQuery *self = GET_POINTER(TSQuery, this, Query_self);
return (jint)ts_query_capture_count(self);
}
-jlong query_get_timeout_micros(JNIEnv *env, jobject this) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- return (jlong)ts_query_cursor_timeout_micros(cursor);
-}
-
-void query_set_timeout_micros(JNIEnv *env, jobject this, jlong value) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- ts_query_cursor_set_timeout_micros(cursor, (uint64_t)value);
- (*env)->SetLongField(env, this, global_field_cache.Query_timeoutMicros, value);
-}
-
-jint query_get_match_limit(JNIEnv *env, jobject this) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- return (jint)ts_query_cursor_match_limit(cursor);
-}
-
-void query_set_match_limit(JNIEnv *env, jobject this, jint value) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- ts_query_cursor_set_match_limit(cursor, (uint32_t)value);
- (*env)->SetIntField(env, this, global_field_cache.Query_matchLimit, value);
-}
-
-void query_set_max_start_depth(JNIEnv *env, jobject this, jint value) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- ts_query_cursor_set_max_start_depth(cursor, (uint32_t)value);
- (*env)->SetIntField(env, this, global_field_cache.Query_maxStartDepth, value);
-}
-
-void query_native_set_byte_range(JNIEnv *env, jobject this, jint start, jint end) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- ts_query_cursor_set_byte_range(cursor, (uint32_t)start, (uint32_t)end);
-}
-
-void query_native_set_point_range(JNIEnv *env, jobject this, jobject start, jobject end) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- TSPoint start_point = unmarshal_point(env, start), end_point = unmarshal_point(env, end);
- ts_query_cursor_set_point_range(cursor, start_point, end_point);
-}
-
-jboolean query_did_exceed_match_limit(JNIEnv *env, jobject this) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- return (jboolean)ts_query_cursor_did_exceed_match_limit(cursor);
-}
-
void query_disable_pattern(JNIEnv *env, jobject this, jint index) {
TSQuery *self = GET_POINTER(TSQuery, this, Query_self);
if (ts_query_pattern_count(self) > (uint32_t)index) {
@@ -177,7 +131,7 @@ void query_disable_pattern(JNIEnv *env, jobject this, jint index) {
}
}
-void query_native_disable_capture(JNIEnv *env, jobject this, jstring capture) {
+void query_disable_capture(JNIEnv *env, jobject this, jstring capture) {
TSQuery *self = GET_POINTER(TSQuery, this, Query_self);
const char *capture_chars = (*env)->GetStringUTFChars(env, capture, NULL);
uint32_t length = (uint32_t)(*env)->GetStringUTFLength(env, capture);
@@ -247,13 +201,6 @@ jint query_string_count(JNIEnv *env, jobject this) {
return (jint)ts_query_string_count(self);
}
-void query_exec(JNIEnv *env, jobject this, jobject node) {
- TSQuery *query = GET_POINTER(TSQuery, this, Query_self);
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- TSNode ts_node = unmarshal_node(env, node);
- ts_query_cursor_exec(cursor, query, ts_node);
-}
-
jstring query_capture_name_for_id(JNIEnv *env, jobject this, jint index) {
TSQuery *self = GET_POINTER(TSQuery, this, Query_self);
uint32_t length;
@@ -287,89 +234,20 @@ jobject query_predicates_for_pattern(JNIEnv *env, jobject this, jint index) {
return predicates;
}
-jobject query_next_match(JNIEnv *env, jobject this, jobject tree) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- TSQueryMatch match;
- if (!ts_query_cursor_next_match(cursor, &match))
- return NULL;
-
- jobject capture_names = GET_FIELD(Object, this, Query_captureNames);
- jobject captures = NEW_OBJECT(ArrayList, (jint)match.capture_count);
- for (uint16_t i = 0; i < match.capture_count; ++i) {
- TSQueryCapture capture = match.captures[i];
- jobject node = marshal_node(env, capture.node, tree);
- jobject name = CALL_METHOD(Object, capture_names, List_get, capture.index);
- if ((*env)->ExceptionCheck(env))
- return NULL;
-
- jobject capture_obj = NEW_OBJECT(QueryCapture, node, name);
- CALL_METHOD(Boolean, captures, ArrayList_add, capture_obj);
- (*env)->DeleteLocalRef(env, capture_obj);
- (*env)->DeleteLocalRef(env, node);
- (*env)->DeleteLocalRef(env, name);
- if ((*env)->ExceptionCheck(env))
- return NULL;
- }
- return NEW_OBJECT(QueryMatch, (jint)match.pattern_index, captures);
-}
-
-jobject query_next_capture(JNIEnv *env, jobject this, jobject tree) {
- TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, Query_cursor);
- uint32_t capture_index;
- TSQueryMatch match;
- if (!ts_query_cursor_next_capture(cursor, &match, &capture_index))
- return NULL;
-
- jobject capture_names = GET_FIELD(Object, this, Query_captureNames);
- jobject captures = NEW_OBJECT(ArrayList, (jint)match.capture_count);
- for (uint16_t i = 0; i < match.capture_count; ++i) {
- TSQueryCapture capture = match.captures[i];
- jobject node = marshal_node(env, capture.node, tree);
- jobject name = CALL_METHOD(Object, capture_names, List_get, capture.index);
- if ((*env)->ExceptionCheck(env))
- return NULL;
-
- jobject capture_obj = NEW_OBJECT(QueryCapture, node, name);
- CALL_METHOD(Boolean, captures, ArrayList_add, capture_obj);
- (*env)->DeleteLocalRef(env, capture_obj);
- (*env)->DeleteLocalRef(env, node);
- (*env)->DeleteLocalRef(env, name);
- if ((*env)->ExceptionCheck(env))
- return NULL;
- }
- jobject match_obj = NEW_OBJECT(QueryMatch, (jint)match.pattern_index, captures);
- jobject index = (*env)->AllocObject(env, global_class_cache.UInt);
- (*env)->SetIntField(env, index, global_field_cache.UInt_data, (jint)capture_index);
- return NEW_OBJECT(Pair, index, match_obj);
-}
-
const JNINativeMethod Query_methods[] = {
{"init", "(JLjava/lang/String;)J", (void *)&query_init},
- {"cursor", "()J", (void *)&query_cursor},
- {"delete", "(JJ)V", (void *)&query_delete},
- {"getPatternCount", "()I", (void *)&query_get_pattern_count},
- {"getCaptureCount", "()I", (void *)&query_get_capture_count},
- {"getTimeoutMicros", "()J", (void *)&query_get_timeout_micros},
- {"setTimeoutMicros", "(J)V", (void *)&query_set_timeout_micros},
- {"getMatchLimit", "()I", (void *)&query_get_match_limit},
- {"setMatchLimit", "(I)V", (void *)&query_set_match_limit},
- {"setMaxStartDepth", "(I)V", (void *)&query_set_max_start_depth},
- {"didExceedMatchLimit", "()Z", (void *)&query_did_exceed_match_limit},
+ {"delete", "(J)V", (void *)&query_delete},
+ {"nativePatternCount", "()I", (void *)&query_native_pattern_count},
+ {"nativeCaptureCount", "()I", (void *)&query_native_capture_count},
{"disablePattern", "(I)V", (void *)&query_disable_pattern},
+ {"disableCapture", "(Ljava/lang/String;)V", (void *)&query_disable_capture},
{"startByteForPattern", "(I)I", (void *)&query_start_byte_for_pattern},
{"endByteForPattern", "(I)I", (void *)&query_end_byte_for_pattern},
{"isPatternRooted", "(I)Z", (void *)&query_is_pattern_rooted},
{"isPatternNonLocal", "(I)Z", (void *)&query_is_pattern_non_local},
{"stringCount", "()I", (void *)&query_string_count},
- {"exec", "(L" PACKAGE "Node;)V", (void *)&query_exec},
- {"nextMatch", "(L" PACKAGE "Tree;)L" PACKAGE "QueryMatch;", (void *)&query_next_match},
- {"nextCapture", "(L" PACKAGE "Tree;)Lkotlin/Pair;", (void *)&query_next_capture},
{"captureNameForId", "(I)Ljava/lang/String;", (void *)&query_capture_name_for_id},
{"stringValueForId", "(I)Ljava/lang/String;", (void *)&query_string_value_for_id},
- {"nativeSetByteRange", "(II)V", (void *)&query_native_set_byte_range},
- {"nativeSetPointRange", "(L" PACKAGE "Point;L" PACKAGE "Point;)V",
- (void *)&query_native_set_point_range},
- {"nativeDisableCapture", "(Ljava/lang/String;)V", (void *)&query_native_disable_capture},
{"nativeIsPatternGuaranteedAtStep", "(I)Z",
(void *)&query_native_is_pattern_guaranteed_at_step},
{"predicatesForPattern", "(I)Ljava/util/List;", (void *)&query_predicates_for_pattern},
diff --git a/ktreesitter/src/jni/query_cursor.c b/ktreesitter/src/jni/query_cursor.c
new file mode 100644
index 0000000..18ff72a
--- /dev/null
+++ b/ktreesitter/src/jni/query_cursor.c
@@ -0,0 +1,151 @@
+#include "utils.h"
+
+static bool query_progress_callback(TSQueryCursorState *state) {
+ ProgressPayload *progress_payload = (ProgressPayload *)state->payload;
+ JNIEnv *env = progress_payload->env;
+ jobject offset = (*env)->AllocObject(env, global_class_cache.UInt);
+ (*env)->SetIntField(env, offset, global_field_cache.UInt_data,
+ (jint)state->current_byte_offset);
+ jobject result = CALL_METHOD(Object, progress_payload->callback, Function1_invoke, offset);
+ (*env)->DeleteLocalRef(env, offset);
+ return (bool)(*env)->GetBooleanField(env, result, global_field_cache.Boolean_value);
+}
+
+jlong query_cursor_init CRITICAL_NO_ARGS() { return (jlong)ts_query_cursor_new(); }
+
+void query_cursor_delete CRITICAL_ARGS(jlong query) { ts_query_delete((TSQuery *)query); }
+
+jlong query_cursor_get_timeout_micros(JNIEnv *env, jobject this) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ return (jlong)ts_query_cursor_timeout_micros(cursor);
+}
+
+void query_cursor_set_timeout_micros(JNIEnv *env, jobject this, jlong value) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ ts_query_cursor_set_timeout_micros(cursor, (uint64_t)value);
+ (*env)->SetLongField(env, this, global_field_cache.QueryCursor_timeoutMicros, value);
+}
+
+jint query_cursor_get_match_limit(JNIEnv *env, jobject this) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ return (jint)ts_query_cursor_match_limit(cursor);
+}
+
+void query_cursor_set_match_limit(JNIEnv *env, jobject this, jint value) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ ts_query_cursor_set_match_limit(cursor, (uint32_t)value);
+ (*env)->SetIntField(env, this, global_field_cache.QueryCursor_matchLimit, value);
+}
+
+void query_cursor_set_max_start_depth(JNIEnv *env, jobject this, jint value) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ ts_query_cursor_set_max_start_depth(cursor, (uint32_t)value);
+ (*env)->SetIntField(env, this, global_field_cache.QueryCursor_maxStartDepth, value);
+}
+
+jboolean query_cursor_did_exceed_match_limit(JNIEnv *env, jobject this) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ return (jboolean)ts_query_cursor_did_exceed_match_limit(cursor);
+}
+
+jboolean query_cursor_native_set_byte_range(JNIEnv *env, jobject this, jint start, jint end) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ return (jboolean)ts_query_cursor_set_byte_range(cursor, (uint32_t)start, (uint32_t)end);
+}
+
+jboolean query_cursor_native_set_point_range(JNIEnv *env, jobject this, jobject start,
+ jobject end) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ TSPoint start_point = unmarshal_point(env, start), end_point = unmarshal_point(env, end);
+ return (jboolean)ts_query_cursor_set_point_range(cursor, start_point, end_point);
+}
+
+void query_cursor_exec(JNIEnv *env, jobject this, jlong query, jobject node,
+ jobject progress_callback) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ TSNode ts_node = unmarshal_node(env, node);
+ if (progress_callback == NULL) {
+ ts_query_cursor_exec(cursor, (TSQuery *)query, ts_node);
+ } else {
+ ProgressPayload progress_payload = {.env = env, .callback = progress_callback};
+ TSQueryCursorOptions options = {
+ .payload = (void *)&progress_payload,
+ .progress_callback = query_progress_callback,
+ };
+ ts_query_cursor_exec_with_options(cursor, (TSQuery *)query, ts_node, &options);
+ }
+}
+
+jobject query_cursor_next_capture(JNIEnv *env, jobject this, jobject capture_names, jobject tree) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ uint32_t capture_index;
+ TSQueryMatch match;
+ if (!ts_query_cursor_next_capture(cursor, &match, &capture_index))
+ return NULL;
+
+ jobject captures = NEW_OBJECT(ArrayList, (jint)match.capture_count);
+ for (uint16_t i = 0; i < match.capture_count; ++i) {
+ TSQueryCapture capture = match.captures[i];
+ jobject node = marshal_node(env, capture.node, tree);
+ jobject name = CALL_METHOD(Object, capture_names, List_get, capture.index);
+ if ((*env)->ExceptionCheck(env))
+ return NULL;
+
+ jobject capture_obj = NEW_OBJECT(QueryCapture, node, name);
+ CALL_METHOD(Boolean, captures, ArrayList_add, capture_obj);
+ (*env)->DeleteLocalRef(env, capture_obj);
+ (*env)->DeleteLocalRef(env, node);
+ (*env)->DeleteLocalRef(env, name);
+ if ((*env)->ExceptionCheck(env))
+ return NULL;
+ }
+ jobject match_obj = NEW_OBJECT(QueryMatch, (jint)match.pattern_index, captures);
+ jobject index = (*env)->AllocObject(env, global_class_cache.UInt);
+ (*env)->SetIntField(env, index, global_field_cache.UInt_data, (jint)capture_index);
+ return NEW_OBJECT(Pair, index, match_obj);
+}
+
+jobject query_cursor_next_match(JNIEnv *env, jobject this, jobject capture_names, jobject tree) {
+ TSQueryCursor *cursor = GET_POINTER(TSQueryCursor, this, QueryCursor_self);
+ TSQueryMatch match;
+ if (!ts_query_cursor_next_match(cursor, &match))
+ return NULL;
+
+ jobject captures = NEW_OBJECT(ArrayList, (jint)match.capture_count);
+ for (uint16_t i = 0; i < match.capture_count; ++i) {
+ TSQueryCapture capture = match.captures[i];
+ jobject node = marshal_node(env, capture.node, tree);
+ jobject name = CALL_METHOD(Object, capture_names, List_get, capture.index);
+ if ((*env)->ExceptionCheck(env))
+ return NULL;
+
+ jobject capture_obj = NEW_OBJECT(QueryCapture, node, name);
+ CALL_METHOD(Boolean, captures, ArrayList_add, capture_obj);
+ (*env)->DeleteLocalRef(env, capture_obj);
+ (*env)->DeleteLocalRef(env, node);
+ (*env)->DeleteLocalRef(env, name);
+ if ((*env)->ExceptionCheck(env))
+ return NULL;
+ }
+ return NEW_OBJECT(QueryMatch, (jint)match.pattern_index, captures);
+}
+
+const JNINativeMethod QueryCursor_methods[] = {
+ {"init", "()J", (void *)&query_cursor_init},
+ {"delete", "(J)V", (void *)&query_cursor_delete},
+ {"getTimeoutMicros", "()J", (void *)&query_cursor_get_timeout_micros},
+ {"setTimeoutMicros", "(J)V", (void *)&query_cursor_set_timeout_micros},
+ {"getMatchLimit", "()I", (void *)&query_cursor_get_match_limit},
+ {"setMatchLimit", "(I)V", (void *)&query_cursor_set_match_limit},
+ {"setMaxStartDepth", "(I)V", (void *)&query_cursor_set_max_start_depth},
+ {"didExceedMatchLimit", "()Z", (void *)&query_cursor_did_exceed_match_limit},
+ {"nativeSetByteRange", "(II)Z", (void *)&query_cursor_native_set_byte_range},
+ {"nativeSetPointRange", "(L" PACKAGE "Point;L" PACKAGE "Point;)Z",
+ (void *)&query_cursor_native_set_point_range},
+ {"nextMatch", "(Ljava/util/List;L" PACKAGE "Tree;)L" PACKAGE "QueryMatch;",
+ (void *)&query_cursor_next_match},
+ {"nextCapture", "(Ljava/util/List;L" PACKAGE "Tree;)Lkotlin/Pair;",
+ (void *)&query_cursor_next_capture},
+};
+
+const size_t QueryCursor_methods_size = sizeof QueryCursor_methods / sizeof(JNINativeMethod);
diff --git a/ktreesitter/src/jni/utils.h b/ktreesitter/src/jni/utils.h
index c6718cb..c27a19f 100644
--- a/ktreesitter/src/jni/utils.h
+++ b/ktreesitter/src/jni/utils.h
@@ -54,12 +54,21 @@
#endif
typedef struct {
+ JNIEnv *env;
+ jobject callback;
+} ProgressPayload;
+
+typedef struct {
+ jfieldID Boolean_value;
jfieldID InputEdit_newEndByte;
jfieldID InputEdit_newEndPoint;
jfieldID InputEdit_oldEndByte;
jfieldID InputEdit_oldEndPoint;
jfieldID InputEdit_startByte;
jfieldID InputEdit_startPoint;
+ jfieldID InputEncoding_UTF_8;
+ jfieldID InputEncoding_UTF_16LE;
+ jfieldID InputEncoding_UTF_16BE;
jfieldID Language_self;
jfieldID LookaheadIterator_self;
jfieldID Node_context;
@@ -75,14 +84,13 @@ typedef struct {
jfieldID Parser_timeoutMicros;
jfieldID Point_column;
jfieldID Point_row;
- jfieldID Query_captureNames;
- jfieldID Query_cursor;
+ jfieldID QueryCursor_matchLimit;
+ jfieldID QueryCursor_maxStartDepth;
+ jfieldID QueryCursor_self;
+ jfieldID QueryCursor_timeoutMicros;
jfieldID Query_language;
- jfieldID Query_matchLimit;
- jfieldID Query_maxStartDepth;
jfieldID Query_self;
jfieldID Query_source;
- jfieldID Query_timeoutMicros;
jfieldID Range_endByte;
jfieldID Range_endPoint;
jfieldID Range_startByte;
@@ -93,20 +101,25 @@ typedef struct {
jfieldID Tree_self;
jfieldID Tree_source;
jfieldID UInt_data;
+ jfieldID UShort_data;
} FieldCache;
typedef struct {
jmethodID ArrayList_add;
jmethodID ArrayList_init;
+ jmethodID Boolean_init;
jmethodID CharSequence_toString;
+ jmethodID Function1_invoke;
jmethodID Function2_invoke;
jmethodID Language_init;
+ jmethodID Language$Metadata_init;
jmethodID List_get;
jmethodID List_size;
jmethodID Node_init;
jmethodID Pair_init;
jmethodID Point_init;
jmethodID QueryCapture_init;
+ jmethodID QueryCursor_init;
jmethodID QueryError$Capture_init;
jmethodID QueryError$Field_init;
jmethodID QueryError$NodeType_init;
@@ -115,19 +128,22 @@ typedef struct {
jmethodID QueryMatch_init;
jmethodID Range_init;
jmethodID Tree_init;
- jmethodID UInt_constructor;
- jmethodID UInt_box;
+ jmethodID Triple_init;
} MethodCache;
typedef struct {
jclass ArrayList;
+ jclass Boolean;
jclass CharSequence;
+ jclass Function1;
jclass Function2;
jclass IllegalArgumentException;
jclass IllegalStateException;
jclass IndexOutOfBoundsException;
jclass InputEdit;
+ jclass InputEncoding;
jclass Language;
+ jclass Language$Metadata;
jclass List;
jclass LookaheadIterator;
jclass Node;
@@ -137,6 +153,7 @@ typedef struct {
jclass Point;
jclass Query;
jclass QueryCapture;
+ jclass QueryCursor;
jclass QueryError$Capture;
jclass QueryError$Field;
jclass QueryError$NodeType;
@@ -146,7 +163,9 @@ typedef struct {
jclass Range;
jclass Tree;
jclass TreeCursor;
+ jclass Triple;
jclass UInt;
+ jclass UShort;
} ClassCache;
extern FieldCache global_field_cache;
diff --git a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt
new file mode 100644
index 0000000..f927ec4
--- /dev/null
+++ b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt
@@ -0,0 +1,14 @@
+package io.github.treesitter.ktreesitter
+
+import java.nio.charset.Charset
+
+/**
+ * The encoding of the input text.
+ *
+ * @since 0.25.0
+ */
+actual enum class InputEncoding(val charset: Charset) {
+ UTF_8(Charsets.UTF_8),
+ UTF_16LE(Charsets.UTF_16LE),
+ UTF_16BE(Charsets.UTF_16BE)
+}
diff --git a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Language.kt b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
index 4cc4037..539c13f 100644
--- a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
+++ b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
@@ -3,12 +3,13 @@ package io.github.treesitter.ktreesitter
/**
* A class that defines how to parse a particular language.
*
- * When a [Language] is generated by the Tree-sitter CLI, it is assigned
- * an ABI [version] number that corresponds to the current CLI version.
+ * When a [Language] is generated by the Tree-sitter CLI, it is assigned an
+ * [ABI version][abiVersion] number that corresponds to the current CLI version.
*
* @constructor Create a new instance from the given language pointer.
* @param language A pointer to a `TSLanguage` cast to [Long].
- * @throws [IllegalArgumentException] If the pointer is invalid or the [version] is incompatible.
+ * @throws [IllegalArgumentException]
+ * If the pointer is invalid or the [version][abiVersion] is incompatible.
*/
actual class Language @Throws(IllegalArgumentException::class) actual constructor(language: Any) {
@JvmField
@@ -19,7 +20,17 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
checkVersion()
}
+ /**
+ * The ABI version number for this language.
+ *
+ * @since 0.25.0
+ */
+ @get:JvmName("getAbiVersion")
+ actual val abiVersion: UInt
+ external get
+
/** The ABI version number for this language. */
+ @Deprecated("version is deprecated", ReplaceWith("abiVersion"), DeprecationLevel.ERROR)
@get:JvmName("getVersion")
actual val version: UInt
external get
@@ -39,6 +50,32 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
actual val fieldCount: UInt
external get
+ /**
+ * The name of the language, if available.
+ *
+ * @since 0.25.0
+ */
+ actual val name: String?
+ external get
+
+ /**
+ * The metadata of the language, if available.
+ *
+ * @since 0.25.0
+ */
+ actual val metadata: Metadata?
+ external get
+
+ /**
+ * The supertype symbols of the language.
+ *
+ * @since 0.25.0
+ */
+ @OptIn(ExperimentalUnsignedTypes::class)
+ @get:JvmName("getSupertypes")
+ actual val supertypes: UShortArray
+ external get
+
/**
* Get another reference to the language.
*
@@ -54,6 +91,16 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
@JvmName("symbolForName")
actual external fun symbolForName(name: String, isNamed: Boolean): UShort
+ /**
+ * Get the subtype symbols for the given supertype symbol
+ *
+ * @since 0.25.0
+ * @see supertypes
+ */
+ @JvmName("subtypes")
+ @OptIn(ExperimentalUnsignedTypes::class)
+ actual external fun subtypes(supertype: UShort): UShortArray
+
/**
* Check if the node for the given numerical ID is named
*
@@ -108,11 +155,12 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
/**
* Create a new [Query] from a string containing one or more S-expression
- * [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax).
+ * [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html).
*
* @throws [QueryError] If any error occurred while creating the query.
*/
@Throws(QueryError::class)
+ @Deprecated("Use the Query constructor instead")
actual fun query(source: String) = Query(this, source)
actual override fun equals(other: Any?) =
@@ -120,11 +168,32 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
actual override fun hashCode() = self.hashCode()
- override fun toString() = "Language(id=0x${self.toString(16)}, version=$version)"
+ override fun toString() = "Language(id=0x${self.toString(16)}, abiVersion=$abiVersion)"
@Throws(IllegalArgumentException::class)
private external fun checkVersion()
+ /**
+ * A class containing the [Language] metadata.
+ *
+ * @property semanticVersion The [Semantic Version](https://semver.org/) of the [Language].
+ */
+ @ConsistentCopyVisibility
+ actual data class Metadata internal actual constructor(
+ @get:JvmName("getSemanticVersion")
+ actual val semanticVersion: Triple
+ ) {
+ actual override fun toString() = buildString {
+ append("Metadata(semanticVersion=\"")
+ append(semanticVersion.first)
+ append('.')
+ append(semanticVersion.second)
+ append('.')
+ append(semanticVersion.third)
+ append("\")")
+ }
+ }
+
private companion object {
@JvmStatic
private external fun copy(self: Long): Long
diff --git a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
index 496caf3..51692a2 100644
--- a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
+++ b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
@@ -71,7 +71,7 @@ actual class LookaheadIterator @Throws(IllegalArgumentException::class) internal
}
}
- override fun computeNext() = if (nativeNext()) {
+ actual override fun computeNext() = if (nativeNext()) {
setNext(Symbol(currentSymbol, currentSymbolName))
} else {
done()
diff --git a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Node.kt b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
index 86e2b72..210af13 100644
--- a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
+++ b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
@@ -205,6 +205,24 @@ actual class Node internal constructor(
@Throws(IndexOutOfBoundsException::class)
actual external fun namedChild(index: UInt): Node?
+ /**
+ * Get the node's first child that contains
+ * or starts after the given byte offset.
+ *
+ * @since 0.25.0
+ */
+ @JvmName("firstChildForByte")
+ actual external fun firstChildForByte(byte: UInt): Node?
+
+ /**
+ * Get the node's first _named_ child that contains
+ * or starts after the given byte offset.
+ *
+ * @since 0.25.0
+ */
+ @JvmName("firstNamedChildForByte")
+ actual external fun firstNamedChildForByte(byte: UInt): Node?
+
/**
* Get the node's child with the given field ID, if any.
*
@@ -244,13 +262,6 @@ actual class Node internal constructor(
@Throws(IndexOutOfBoundsException::class)
actual external fun fieldNameForNamedChild(index: UInt): String?
- /** Get the child of the node that contains the given descendant, if any. */
- @Deprecated(
- "This method will not return a direct descendant",
- ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
- )
- actual external fun childContainingDescendant(descendant: Node): Node?
-
/**
* Get the node that contains the given descendant, if any.
*
diff --git a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
index fe32fe7..6ef25ef 100644
--- a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
+++ b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
@@ -44,6 +44,7 @@ actual class Parser actual constructor() {
*/
@get:JvmName("getTimeoutMicros")
@set:JvmName("setTimeoutMicros")
+ @Deprecated("Use the progressCallback in parse()")
actual var timeoutMicros: ULong
external get
external set
@@ -84,11 +85,10 @@ actual class Parser actual constructor() {
* [Tree.edit] method in a way that exactly matches the source code changes.
*
* @throws [IllegalStateException]
- * If the parser does not have a [language] assigned or
- * if parsing was cancelled due to a [timeout][timeoutMicros].
+ * If the parser does not have a [language] assigned or if parsing was halted.
*/
@Throws(IllegalStateException::class)
- actual external fun parse(source: String, oldTree: Tree?): Tree
+ actual external fun parse(source: String, encoding: InputEncoding, oldTree: Tree?): Tree
/**
* Parse source code from a callback and create a syntax tree.
@@ -100,19 +100,22 @@ actual class Parser actual constructor() {
* [Tree.edit] method in a way that exactly matches the source code changes.
*
* @throws [IllegalStateException]
- * If the parser does not have a [language] assigned or
- * if parsing was cancelled due to a [timeout][timeoutMicros].
+ * If the parser does not have a [language] assigned or if parsing was halted.
*/
@Throws(IllegalStateException::class)
- actual external fun parse(oldTree: Tree?, callback: ParseCallback): Tree
+ actual external fun parse(
+ encoding: InputEncoding,
+ oldTree: Tree?,
+ progressCallback: ParseProgressCallback?,
+ readCallback: ParseReadCallback
+ ): Tree
/**
* Instruct the parser to start the next [parse] from the beginning.
*
- * If the parser previously failed because of a [timeout][timeoutMicros],
- * then by default, it will resume where it left off. If you don't
- * want to resume, and instead intend to use this parser to parse
- * some other document, you must call this method first.
+ * If parsing was previously halted, then by default, it will resume where
+ * it left off. If you don't want to resume, and instead intend to use this
+ * parser to parse some other document, you must call this method first.
*/
actual external fun reset()
diff --git a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Query.kt b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
index e073be7..0cef67b 100644
--- a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
+++ b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
@@ -1,24 +1,12 @@
package io.github.treesitter.ktreesitter
-/**
- * A class that represents a set of patterns which match nodes in a syntax tree.
- *
- * @constructor
- * Create a new query from a particular language and a
- * string containing one or more S-expression patterns.
- * @throws [QueryError] If any error occurred while creating the query.
- */
actual class Query @Throws(QueryError::class) actual constructor(
private val language: Language,
private val source: String
) {
- private val self: Long = init(language.self, source)
+ internal val self: Long = init(language.self, source)
- private val cursor: Long = cursor()
-
- private val captureNames: MutableList
-
- private val predicates: List>
+ internal val predicates: List>
private val settingList: List>
@@ -27,25 +15,40 @@ actual class Query @Throws(QueryError::class) actual constructor(
/** The number of patterns in the query. */
@get:JvmName("getPatternCount")
actual val patternCount: UInt
- external get
+ get() = nativePatternCount().toUInt()
/** The number of captures in the query. */
@get:JvmName("getCaptureCount")
+ @Deprecated("captureCount is deprecated.", ReplaceWith("captureNames.size"))
actual val captureCount: UInt
- external get
+ get() = nativeCaptureCount().toUInt()
+
+ /**
+ * The capture names used in the query.
+ *
+ * @since 0.25.0
+ */
+ actual val captureNames: List
+
+ /**
+ * The string literals used in the query.
+ *
+ * @since 0.25.0
+ */
+ actual val stringValues: List
init {
- RefCleaner(this, CleanAction(self, cursor))
+ RefCleaner(this, CleanAction(self))
- predicates = List(patternCount.toInt()) { mutableListOf() }
- settingList = List(patternCount.toInt()) { mutableMapOf() }
- assertionList = List(patternCount.toInt()) { mutableMapOf() }
- captureNames = MutableList(captureCount.toInt()) {
+ predicates = List(nativePatternCount()) { mutableListOf() }
+ settingList = List(nativePatternCount()) { mutableMapOf() }
+ assertionList = List(nativePatternCount()) { mutableMapOf() }
+ captureNames = List(nativeCaptureCount()) {
checkNotNull(captureNameForId(it)) {
"Failed to get capture name at index $it"
}
}
- val stringValues = List(stringCount()) {
+ stringValues = List(stringCount()) {
checkNotNull(stringValueForId(it)) {
"Failed to get string value at index $it"
}
@@ -262,132 +265,14 @@ actual class Query @Throws(QueryError::class) actual constructor(
}
/**
- * The maximum duration in microseconds that query
- * execution should be allowed to take before halting.
- *
- * Default: `0`
- *
- * @since 0.23.0
- */
- @get:JvmName("getTimeoutMicros")
- @set:JvmName("setTimeoutMicros")
- actual var timeoutMicros: ULong
- external get
- external set
-
- /**
- * The maximum number of in-progress matches.
- *
- * Default: `UInt.MAX_VALUE`
- *
- * @throws [IllegalArgumentException] If the match limit is set to `0`.
- */
- @get:JvmName("getMatchLimit")
- @set:JvmName("setMatchLimit")
- actual var matchLimit: UInt
- external get
- external set
-
- /**
- * The maximum start depth for the query.
- *
- * This prevents cursors from exploring children nodes at a certain depth.
- * Note that if a pattern includes many children, then they will still be checked.
- *
- * Default: `UInt.MAX_VALUE`
- */
- @get:JvmName("getMaxStartDepth")
- @set:JvmName("setMaxStartDepth")
- actual var maxStartDepth: UInt = UInt.MAX_VALUE
- external set
-
- /**
- * The range of bytes in which the query will be executed.
- *
- * Default: `UInt.MIN_VALUE..UInt.MAX_VALUE`
- */
- actual var byteRange: UIntRange = UInt.MIN_VALUE..UInt.MAX_VALUE
- set(value) {
- nativeSetByteRange(value.first.toInt(), value.last.toInt())
- field = value
- }
-
- /**
- * The range of points in which the query will be executed.
- *
- * Default: `Point.MIN..Point.MAX`
- */
- actual var pointRange: ClosedRange = Point.MIN..Point.MAX
- set(value) {
- nativeSetPointRange(value.start, value.endInclusive)
- field = value
- }
-
- /**
- * Check if the query exceeded its maximum number of
- * in-progress matches during its last execution.
- */
- @get:JvmName("didExceedMatchLimit")
- actual val didExceedMatchLimit: Boolean
- external get
-
- /**
- * Iterate over all the matches in the order that they were found.
- *
- * #### Example
- *
- * ```kotlin
- * query.matches(tree.rootNode) {
- * if (name != "ieq?") return@matches true
- * val node = it[(args[0] as QueryPredicateArg.Capture).value].first()
- * val value = (args[1] as QueryPredicateArg.Literal).value
- * value.equals(node.text()?.toString(), ignoreCase = true)
- * }
- * ```
- *
- * @param node The node that the query will run on.
- * @param predicate A function that handles custom predicates.
- */
- @JvmOverloads
- actual fun matches(
- node: Node,
- predicate: QueryPredicate.(QueryMatch) -> Boolean
- ): Sequence {
- exec(node)
- return sequence {
- var match = nextMatch(node.tree)
- while (match != null) {
- val result = match.check(node.tree, predicate)
- if (result != null) yield(result)
- match = nextMatch(node.tree)
- }
- }
- }
-
- /**
- * Iterate over all the individual captures in the order that they appear.
- *
- * This is useful if you don't care about _which_ pattern matched.
+ * Execute the query on the given [Node].
*
- * @param node The node that the query will run on.
- * @param predicate A function that handles custom predicates.
+ * @since 0.25.0
*/
@JvmOverloads
- actual fun captures(
- node: Node,
- predicate: QueryPredicate.(QueryMatch) -> Boolean
- ): Sequence> {
- exec(node)
- return sequence {
- var capture = nextCapture(node.tree)
- while (capture != null) {
- val index = capture.first
- val match = capture.second.check(node.tree, predicate)
- if (match != null) yield(index to match)
- capture = nextCapture(node.tree)
- }
- }
- }
+ @JvmName("exec")
+ actual operator fun invoke(node: Node, progressCallback: QueryProgressCallback?) =
+ QueryCursor(this, node, progressCallback)
/**
* Get the property settings for the given pattern index.
@@ -444,15 +329,8 @@ actual class Query @Throws(QueryError::class) actual constructor(
* This prevents the capture from being returned in matches,
* and also avoids most resource usage associated with recording
* the capture. Currently, there is no way to undo this.
- *
- * @throws [NoSuchElementException] If the capture does not exist.
*/
- @Throws(NoSuchElementException::class)
- actual fun disableCapture(name: String) {
- if (!captureNames.remove(name))
- throw NoSuchElementException("Capture @$name does not exist")
- nativeDisableCapture(name)
- }
+ actual external fun disableCapture(name: String)
/**
* Get the byte offset where the given pattern starts in the query's source.
@@ -514,39 +392,20 @@ actual class Query @Throws(QueryError::class) actual constructor(
override fun toString() = "Query(language=$language, source=$source)"
- private external fun stringCount(): Int
-
- private external fun exec(node: Node)
+ private external fun nativePatternCount(): Int
- private external fun nextMatch(tree: Tree): QueryMatch?
+ private external fun nativeCaptureCount(): Int
- private external fun nextCapture(tree: Tree): Pair?
+ private external fun stringCount(): Int
private external fun captureNameForId(index: Int): String?
private external fun stringValueForId(index: Int): String?
- private external fun nativeSetByteRange(start: Int, end: Int)
-
- private external fun nativeSetPointRange(start: Point, end: Point)
-
- private external fun nativeDisableCapture(name: String)
-
private external fun nativeIsPatternGuaranteedAtStep(index: Int): Boolean
private external fun predicatesForPattern(index: Int): List?
- private inline fun QueryMatch.check(
- tree: Tree,
- predicate: QueryPredicate.(QueryMatch) -> Boolean
- ): QueryMatch? {
- if (tree.text() == null) return this
- val result = predicates[patternIndex].all {
- if (it !is QueryPredicate.Generic) it(this) else predicate(it, this)
- }
- return if (result) this else null
- }
-
@Suppress("NOTHING_TO_INLINE")
private inline operator fun List.get(index: UInt) = get(index.toInt())
@@ -556,8 +415,8 @@ actual class Query @Throws(QueryError::class) actual constructor(
private inline val IntArray.type: Int
inline get() = get(1)
- private class CleanAction(private val query: Long, private val cursor: Long) : Runnable {
- override fun run() = delete(query, cursor)
+ private class CleanAction(private val ptr: Long) : Runnable {
+ override fun run() = delete(ptr)
}
@Suppress("ConstPropertyName")
@@ -573,9 +432,6 @@ actual class Query @Throws(QueryError::class) actual constructor(
private external fun init(language: Long, query: String): Long
@JvmStatic
- private external fun cursor(): Long
-
- @JvmStatic
- private external fun delete(query: Long, cursor: Long)
+ private external fun delete(self: Long)
}
}
diff --git a/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt
new file mode 100644
index 0000000..5c4b185
--- /dev/null
+++ b/ktreesitter/src/jvmMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt
@@ -0,0 +1,194 @@
+package io.github.treesitter.ktreesitter
+
+/**
+ * A class that is used for executing a query.
+ *
+ * @since 0.25.0
+ */
+actual class QueryCursor internal constructor(
+ private val query: Query,
+ private val node: Node,
+ progressCallback: QueryProgressCallback? = null
+) {
+ private val self: Long = init()
+
+ init {
+ RefCleaner(this, CleanAction(self))
+
+ exec(query.self, node, progressCallback)
+ }
+
+ /**
+ * The maximum duration in microseconds that query
+ * execution should be allowed to take before halting.
+ *
+ * Default: `0`
+ *
+ * @since 0.23.0
+ */
+ @get:JvmName("getTimeoutMicros")
+ @set:JvmName("setTimeoutMicros")
+ @Deprecated("Use the progressCallback in Query.invoke()")
+ actual var timeoutMicros: ULong
+ external get
+
+ external set
+
+ /**
+ * The maximum number of in-progress matches.
+ *
+ * Default: `UInt.MAX_VALUE`
+ *
+ * @throws [IllegalArgumentException] If the match limit is set to `0`.
+ */
+ @get:JvmName("getMatchLimit")
+ @set:JvmName("setMatchLimit")
+ @set:Throws(IllegalArgumentException::class)
+ actual var matchLimit: UInt
+ external get
+
+ external set
+
+ /**
+ * The maximum start depth for the query.
+ *
+ * This prevents cursors from exploring children nodes at a certain depth.
+ * Note that if a pattern includes many children, then they will still be checked.
+ *
+ * Default: `UInt.MAX_VALUE`
+ */
+ @get:JvmName("getMaxStartDepth")
+ @set:JvmName("setMaxStartDepth")
+ actual var maxStartDepth: UInt = UInt.MAX_VALUE
+ external set
+
+ /**
+ * The range of bytes in which the query will be executed.
+ *
+ * The query cursor will return matches that intersect with
+ * the given range. This means that a match may be returned
+ * even if some of its captures fall outside the specified range,
+ * as long as at least part of the match overlaps with the range.
+ *
+ * Default: `UInt.MIN_VALUE..UInt.MAX_VALUE`
+ *
+ * @throws [IllegalArgumentException] If set to an invalid range.
+ */
+ actual var byteRange: UIntRange = UInt.MIN_VALUE..UInt.MAX_VALUE
+ set(value) {
+ require(nativeSetByteRange(value.first.toInt(), value.last.toInt())) {
+ "Invalid byte range: [${value.first}, ${value.last}]"
+ }
+ field = value
+ }
+
+ /**
+ * The range of points in which the query will be executed.
+ *
+ * The query cursor will return matches that intersect with
+ * the given range. This means that a match may be returned
+ * even if some of its captures fall outside the specified range,
+ * as long as at least part of the match overlaps with the range.
+ *
+ * Default: `Point.MIN..Point.MAX`
+ */
+ actual var pointRange: ClosedRange = Point.MIN..Point.MAX
+ set(value) {
+ require(nativeSetPointRange(value.start, value.endInclusive)) {
+ "Invalid point range: [${value.start}, ${value.endInclusive}]"
+ }
+ field = value
+ }
+
+ /**
+ * Check if the query exceeded its maximum number of
+ * in-progress matches during its last execution.
+ *
+ * @see matchLimit
+ */
+ @get:JvmName("didExceedMatchLimit")
+ actual val didExceedMatchLimit: Boolean
+ external get
+
+ /**
+ * Iterate over all the matches in the order that they were found.
+ *
+ * #### Example
+ *
+ * ```kotlin
+ * query(tree.rootNode).matches {
+ * if (name != "ieq?") return@matches true
+ * val node = it[(args[0] as QueryPredicateArg.Capture).value].first()
+ * val value = (args[1] as QueryPredicateArg.Literal).value
+ * value.equals(node.text()?.toString(), ignoreCase = true)
+ * }
+ * ```
+ *
+ * @param predicate A function that handles custom predicates.
+ */
+ @JvmOverloads
+ actual fun matches(predicate: QueryPredicate.(QueryMatch) -> Boolean) = sequence {
+ var match = nextMatch(query.captureNames, node.tree)
+ while (match != null) {
+ val result = match.check(predicate)
+ if (result != null) yield(result)
+ match = nextMatch(query.captureNames, node.tree)
+ }
+ }
+
+ /**
+ * Iterate over all the individual captures in the order that they appear.
+ *
+ * This is useful if you don't care about _which_ pattern matched.
+ *
+ * @param predicate A function that handles custom predicates.
+ */
+ @JvmOverloads
+ actual fun captures(predicate: QueryPredicate.(QueryMatch) -> Boolean) =
+ sequence> {
+ var capture = nextCapture(query.captureNames, node.tree)
+ while (capture != null) {
+ val index = capture.first
+ val match = capture.second.check(predicate)
+ if (match != null) yield(index to match)
+ capture = nextCapture(query.captureNames, node.tree)
+ }
+ }
+
+ override fun toString() = "QueryCursor(query=$query, node=$node)"
+
+ private external fun nativeSetByteRange(start: Int, end: Int): Boolean
+
+ private external fun nativeSetPointRange(start: Point, end: Point): Boolean
+
+ private external fun nextMatch(captureNames: List, tree: Tree): QueryMatch?
+
+ private external fun nextCapture(
+ captureNames: List,
+ tree: Tree
+ ): Pair?
+
+ private external fun exec(query: Long, node: Node, progressCallback: QueryProgressCallback?)
+
+ private inline fun QueryMatch.check(
+ predicate: QueryPredicate.(QueryMatch) -> Boolean
+ ): QueryMatch? {
+ if (node.tree.text() == null) return this
+ val result = query.predicates[patternIndex.toInt()].all {
+ if (it !is QueryPredicate.Generic) it(this) else predicate(it, this)
+ }
+ return if (result) this else null
+ }
+
+ private class CleanAction(private val ptr: Long) : Runnable {
+ override fun run() = delete(ptr)
+ }
+
+ private companion object {
+ @JvmStatic
+ private external fun init(): Long
+
+ @JvmStatic
+ private external fun delete(self: Long)
+ }
+}
diff --git a/ktreesitter/src/nativeInterop/cinterop/treesitter.def b/ktreesitter/src/nativeInterop/cinterop/treesitter.def
index 3e2a4fc..c7f5608 100644
--- a/ktreesitter/src/nativeInterop/cinterop/treesitter.def
+++ b/ktreesitter/src/nativeInterop/cinterop/treesitter.def
@@ -1,14 +1,14 @@
package = io.github.treesitter.ktreesitter.internal
headers = tree_sitter/api.h alloc.h
headerFilter = tree_sitter/api.h
-compilerOpts = -DTREE_SITTER_HIDE_SYMBOLS
+compilerOpts = -DTREE_SITTER_HIDE_SYMBOLS -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L
staticLibraries = libtree-sitter.a
strictEnums = \
+ TSInputEncoding \
TSLogType \
TSQuantifier \
TSQueryError
nonStrictEnums = \
- TSInputEncoding \
TSQueryPredicateStepType \
TSSymbolType
excludedFunctions = \
diff --git a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt
new file mode 100644
index 0000000..15d1d02
--- /dev/null
+++ b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/InputEncoding.kt
@@ -0,0 +1,16 @@
+package io.github.treesitter.ktreesitter
+
+import io.github.treesitter.ktreesitter.internal.TSInputEncoding
+import kotlinx.cinterop.ExperimentalForeignApi
+
+/**
+ * The encoding of the input text.
+ *
+ * @since 0.25.0
+ */
+@OptIn(ExperimentalForeignApi::class)
+actual enum class InputEncoding(internal val value: TSInputEncoding) {
+ UTF_8(TSInputEncoding.TSInputEncodingUTF8),
+ UTF_16LE(TSInputEncoding.TSInputEncodingUTF16LE),
+ UTF_16BE(TSInputEncoding.TSInputEncodingUTF16BE)
+}
diff --git a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Language.kt b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
index 56b7595..9663142 100644
--- a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
+++ b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Language.kt
@@ -7,8 +7,8 @@ import kotlinx.cinterop.*
/**
* A class that defines how to parse a particular language.
*
- * When a [Language] is generated by the Tree-sitter CLI, it is assigned
- * an ABI [version] number that corresponds to the current CLI version.
+ * When a [Language] is generated by the Tree-sitter CLI, it is assigned an
+ * [ABI version][abiVersion] number that corresponds to the current CLI version.
*/
@OptIn(ExperimentalForeignApi::class) actual class Language internal constructor(
internal val self: CPointer
@@ -18,7 +18,7 @@ import kotlinx.cinterop.*
*
* @param language A [CPointer] to a `TSLanguage`.
* @throws [IllegalArgumentException]
- * If the pointer is invalid or the [version] is incompatible.
+ * If the pointer is invalid or the [version][abiVersion] is incompatible.
*/
@Throws(IllegalArgumentException::class)
actual constructor(language: Any) : this(
@@ -26,16 +26,24 @@ import kotlinx.cinterop.*
?: throw IllegalArgumentException("Invalid language: $language")
)
- /** The ABI version number for this language. */
- actual val version: UInt = ts_language_version(self)
+ /**
+ * The ABI version number for this language.
+ *
+ * @since 0.25.0
+ */
+ actual val abiVersion: UInt = ts_language_abi_version(self)
init {
- require(version in MIN_COMPATIBLE_LANGUAGE_VERSION..LANGUAGE_VERSION) {
- "Incompatible language version $version. " +
+ require(abiVersion in MIN_COMPATIBLE_LANGUAGE_VERSION..LANGUAGE_VERSION) {
+ "Incompatible language version $abiVersion. " +
"Must be between $MIN_COMPATIBLE_LANGUAGE_VERSION and $LANGUAGE_VERSION."
}
}
+ /** The ABI version number for this language. */
+ @Deprecated("version is deprecated", ReplaceWith("abiVersion"), DeprecationLevel.ERROR)
+ actual val version = abiVersion
+
/** The number of distinct node types in this language. */
actual val symbolCount: UInt = ts_language_symbol_count(self)
@@ -45,6 +53,42 @@ import kotlinx.cinterop.*
/** The number of distinct field names in this language. */
actual val fieldCount: UInt = ts_language_field_count(self)
+ /**
+ * The name of the language, if available.
+ *
+ * @since 0.25.0
+ */
+ actual val name: String? = ts_language_name(self)?.toKString()
+
+ /**
+ * The metadata of the language, if available.
+ *
+ * @since 0.25.0
+ */
+ actual val metadata: Metadata?
+ get() = ts_language_metadata(self)?.pointed?.run {
+ Metadata(
+ Triple(
+ major_version.convert(),
+ minor_version.convert(),
+ patch_version.convert()
+ )
+ )
+ }
+
+ /**
+ * The supertype symbols of the language.
+ *
+ * @since 0.25.0
+ */
+ @OptIn(ExperimentalUnsignedTypes::class)
+ actual val supertypes: UShortArray
+ get() = memScoped {
+ val length = alloc()
+ val supertypes = ts_language_supertypes(self, length.ptr) ?: return ushortArrayOf()
+ return UShortArray(length.value.convert()) { supertypes[it] }
+ }
+
/**
* Get another reference to the language.
*
@@ -59,6 +103,19 @@ import kotlinx.cinterop.*
actual fun symbolForName(name: String, isNamed: Boolean): UShort =
ts_language_symbol_for_name(self, name, name.length.convert(), isNamed)
+ /**
+ * Get the subtype symbols for the given supertype symbol
+ *
+ * @since 0.25.0
+ * @see supertypes
+ */
+ @OptIn(ExperimentalUnsignedTypes::class)
+ actual fun subtypes(supertype: UShort): UShortArray = memScoped {
+ val length = alloc()
+ val supertypes = ts_language_subtypes(self, supertype, length.ptr) ?: return ushortArrayOf()
+ return UShortArray(length.value.convert()) { supertypes[it] }
+ }
+
/**
* Check if the node for the given numerical ID is named
*
@@ -106,22 +163,43 @@ import kotlinx.cinterop.*
*
* @throws [IllegalArgumentException] If the state is invalid for this language.
*/
- @Throws(
- IllegalArgumentException::class
- ) actual fun lookaheadIterator(state: UShort) = LookaheadIterator(this, state)
+ @Throws(IllegalArgumentException::class)
+ actual fun lookaheadIterator(state: UShort) = LookaheadIterator(this, state)
/**
* Create a new [Query] from a string containing one or more S-expression
- * [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax).
+ * [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html).
*
* @throws [QueryError] If any error occurred while creating the query.
*/
- @Throws(QueryError::class) actual fun query(source: String) = Query(this, source)
+ @Throws(QueryError::class)
+ @Deprecated("Use the Query constructor instead")
+ actual fun query(source: String) = Query(this, source)
actual override fun equals(other: Any?) =
this === other || (other is Language && self == other.self)
actual override fun hashCode() = self.hashCode()
- override fun toString() = "Language(id=${self.rawValue}, version=$version)"
+ override fun toString() = "Language(id=${self.rawValue}, abiVersion=$abiVersion)"
+
+ /**
+ * A class containing the [Language] metadata.
+ *
+ * @property semanticVersion The [Semantic Version](https://semver.org/) of the [Language].
+ */
+ @ConsistentCopyVisibility
+ actual data class Metadata internal actual constructor(
+ actual val semanticVersion: Triple
+ ) {
+ actual override fun toString() = buildString {
+ append("Metadata(semanticVersion=\"")
+ append(semanticVersion.first)
+ append('.')
+ append(semanticVersion.second)
+ append('.')
+ append(semanticVersion.third)
+ append("\")")
+ }
+ }
}
diff --git a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
index 1b1c8ec..b542d5e 100644
--- a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
+++ b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/LookaheadIterator.kt
@@ -79,7 +79,7 @@ actual class LookaheadIterator @Throws(IllegalArgumentException::class) internal
}
}
- override fun computeNext() = if (ts_lookahead_iterator_next(self)) {
+ actual override fun computeNext() = if (ts_lookahead_iterator_next(self)) {
val id = ts_lookahead_iterator_current_symbol(self)
val name = ts_lookahead_iterator_current_symbol_name(self)
setNext(Symbol(id, name!!.toKString()))
diff --git a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Node.kt b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
index 9300596..c5b5f8a 100644
--- a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
+++ b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Node.kt
@@ -212,6 +212,24 @@ actual class Node internal constructor(
throw IndexOutOfBoundsException("Child index $index is out of bounds")
}
+ /**
+ * Get the node's first child that contains
+ * or starts after the given byte offset.
+ *
+ * @since 0.25.0
+ */
+ actual fun firstChildForByte(byte: UInt) =
+ ts_node_first_child_for_byte(self, byte).convert(tree)
+
+ /**
+ * Get the node's first _named_ child that contains
+ * or starts after the given byte offset.
+ *
+ * @since 0.25.0
+ */
+ actual fun firstNamedChildForByte(byte: UInt) =
+ ts_node_first_named_child_for_byte(self, byte).convert(tree)
+
/**
* Get the node's child with the given field ID, if any.
*
@@ -268,14 +286,6 @@ actual class Node internal constructor(
throw IndexOutOfBoundsException("Child index $index is out of bounds")
}
- /** Get the child of the node that contains the given descendant, if any. */
- @Deprecated(
- "This method will not return a direct descendant",
- ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
- )
- actual fun childContainingDescendant(descendant: Node) =
- ts_node_child_containing_descendant(self, descendant.self).convert(tree)
-
/**
* Get the node that contains the given descendant, if any.
*
diff --git a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
index 654707b..c2fdd04 100644
--- a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
+++ b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt
@@ -69,6 +69,7 @@ actual class Parser actual constructor() {
* The maximum duration in microseconds that parsing
* should be allowed to take before halting.
*/
+ @Deprecated("Use the progressCallback in parse()")
actual var timeoutMicros: ULong
get() = ts_parser_timeout_micros(self)
set(value) = ts_parser_set_timeout_micros(self, value)
@@ -106,19 +107,19 @@ actual class Parser actual constructor() {
* [Tree.edit] method in a way that exactly matches the source code changes.
*
* @throws [IllegalStateException]
- * If the parser does not have a [language] assigned or
- * if parsing was canceled due to a [timeout][timeoutMicros].
+ * If the parser does not have a [language] assigned or if parsing was halted.
*/
@Throws(IllegalStateException::class)
- actual fun parse(source: String, oldTree: Tree?): Tree {
+ actual fun parse(source: String, encoding: InputEncoding, oldTree: Tree?): Tree {
val language = checkNotNull(language) {
"The parser has no language assigned"
}
- val tree = ts_parser_parse_string(
+ val tree = ts_parser_parse_string_encoding(
self,
oldTree?.self,
source,
- source.length.convert()
+ source.length.convert(),
+ encoding.value
)
checkNotNull(tree) { "Parsing failed" }
return Tree(tree, source, language)
@@ -134,19 +135,23 @@ actual class Parser actual constructor() {
* [Tree.edit] method in a way that exactly matches the source code changes.
*
* @throws [IllegalStateException]
- * If the parser does not have a [language] assigned or
- * if parsing was cancelled due to a [timeout][timeoutMicros].
+ * If the parser does not have a [language] assigned or if parsing was halted.
*/
@Throws(IllegalStateException::class)
- actual fun parse(oldTree: Tree?, callback: ParseCallback): Tree {
+ actual fun parse(
+ encoding: InputEncoding,
+ oldTree: Tree?,
+ progressCallback: ParseProgressCallback?,
+ readCallback: ParseReadCallback
+ ): Tree {
val language = checkNotNull(language) {
"The parser has no language assigned"
}
val arena = Arena()
- val payloadRef = StableRef.create(ParsePayload(arena, callback))
+ val payloadRef = StableRef.create(ParsePayload(arena, readCallback))
val input = cValue {
payload = payloadRef.asCPointer()
- encoding = TSInputEncodingUTF8
+ this.encoding = encoding.value
read = staticCFunction { payload, index, point, bytes ->
val data = payload!!.asStableRef().get()
val result = data.callback(index, point.useContents { convert() })
@@ -154,9 +159,24 @@ actual class Parser actual constructor() {
result?.toString()?.cstr?.getPointer(data.memScope)
}
}
- val tree = ts_parser_parse(self, oldTree?.self, input)
+ var progressRef: StableRef? = null
+ val tree = if (progressCallback == null) {
+ ts_parser_parse(self, oldTree?.self, input)
+ } else {
+ progressRef = StableRef.create(progressCallback)
+ val options = cValue {
+ payload = progressRef.asCPointer()
+ progress_callback = staticCFunction { state ->
+ val callback = state!!.pointed.payload!!
+ .asStableRef().get()
+ callback(state.pointed.current_byte_offset, state.pointed.has_error)
+ }
+ }
+ ts_parser_parse_with_options(self, oldTree?.self, input, options)
+ }
arena.clear()
payloadRef.dispose()
+ progressRef?.dispose()
checkNotNull(tree) { "Parsing failed" }
return Tree(tree, null, language)
}
@@ -164,10 +184,9 @@ actual class Parser actual constructor() {
/**
* Instruct the parser to start the next [parse] from the beginning.
*
- * If the parser previously failed because of a [timeout][timeoutMicros],
- * then by default, it will resume where it left off. If you don't
- * want to resume, and instead intend to use this parser to parse
- * some other document, you must call this method first.
+ * If parsing was previously halted, then by default, it will resume where
+ * it left off. If you don't want to resume, and instead intend to use this
+ * parser to parse some other document, you must call this method first.
*/
actual fun reset() = ts_parser_reset(self)
@@ -178,11 +197,11 @@ actual class Parser actual constructor() {
private class ParsePayload(
val memScope: AutofreeScope,
- val callback: ParseCallback
+ val callback: ParseReadCallback
)
private companion object {
- private inline fun freeLogger(logger: CValue) {
+ private fun freeLogger(logger: CValue) {
val arena = Arena()
interpretNullablePointed(
arena.alloc(logger.size, logger.align).rawPtr
diff --git a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Query.kt b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
index bd860de..10b8891 100644
--- a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
+++ b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Query.kt
@@ -1,7 +1,5 @@
package io.github.treesitter.ktreesitter
-import cnames.structs.TSQuery
-import cnames.structs.TSQueryCursor
import io.github.treesitter.ktreesitter.internal.*
import kotlin.experimental.ExperimentalNativeApi
import kotlin.native.ref.createCleaner
@@ -20,109 +18,55 @@ actual class Query @Throws(QueryError::class) actual constructor(
private val language: Language,
private val source: String
) {
- private val self: CPointer
-
- private val cursor: CPointer
-
- private val captureNames: MutableList
-
- private val predicates: List>
-
- private val settings: List>
-
- private val assertions: List>>
+ internal val self = init(language, source)
/** The number of patterns in the query. */
- actual val patternCount: UInt
+ actual val patternCount: UInt = ts_query_pattern_count(self)
/** The number of captures in the query. */
+ @Deprecated("captureCount is deprecated", ReplaceWith("captureNames.size"))
actual val captureCount: UInt
+ get() = ts_query_capture_count(self)
- init {
- val arena = Arena()
- val errorOffset = arena.alloc()
- val errorType = arena.alloc()
- val query = ts_query_new(
- language.self,
- source,
- source.length.convert(),
- errorOffset.ptr,
- errorType.ptr
- )
-
- if (query == null) {
- var start = 0U
- var row = 0U
- val offset = errorOffset.value
- for (line in source.splitToSequence('\n')) {
- val lineEnd = start + line.length.toUInt() + 1U
- if (lineEnd > offset) break
- start = lineEnd
- row += 1U
- }
- val column = offset - start
+ internal val predicates = List(patternCount.toInt()) { mutableListOf() }
- val exception = when (errorType.value) {
- TSQueryError.TSQueryErrorSyntax -> {
- if (offset < source.length.toUInt()) {
- QueryError.Syntax(row.toLong(), column.toLong())
- } else {
- QueryError.Syntax(-1, -1)
- }
- }
- TSQueryError.TSQueryErrorCapture -> {
- val suffix = source.subSequence(offset.toInt(), source.length)
- val end = suffix.indexOfFirst { !kts_is_valid_predicate_char(it.code) }
- val error = suffix.subSequence(0, end.takeIf { it > -1 } ?: suffix.length)
- QueryError.Capture(row, column, error.toString())
- }
- TSQueryError.TSQueryErrorNodeType -> {
- val suffix = source.subSequence(offset.toInt(), source.length)
- val end = suffix.indexOfFirst { !kts_is_valid_identifier_char(it.code) }
- val error = suffix.subSequence(0, end.takeIf { it > -1 } ?: suffix.length)
- QueryError.NodeType(row, column, error.toString())
- }
- TSQueryError.TSQueryErrorField -> {
- val suffix = source.subSequence(offset.toInt(), source.length)
- val end = suffix.indexOfFirst { !kts_is_valid_identifier_char(it.code) }
- val error = suffix.subSequence(0, end.takeIf { it > -1 } ?: suffix.length)
- QueryError.Field(row, column, error.toString())
- }
- TSQueryError.TSQueryErrorStructure -> QueryError.Structure(row, column)
- // language errors are handled in the Language class
- else -> IllegalStateException("Unexpected query error")
- }
- arena.clear()
- throw exception
- }
- arena.clear()
-
- self = query
- cursor = ts_query_cursor_new()!!
- patternCount = ts_query_pattern_count(self)
- captureCount = ts_query_capture_count(self)
- predicates = List(patternCount.toInt()) { mutableListOf() }
- settings = List(patternCount.toInt()) { mutableMapOf() }
- assertions = List(patternCount.toInt()) { mutableMapOf() }
- captureNames = MutableList(captureCount.toInt()) {
- memScoped {
- val length = alloc()
- val name = ts_query_capture_name_for_id(self, it.convert(), length.ptr)
- if (name == null || length.value == 0U)
- error("Failed to get capture name at index $it")
- name.toKString()
- }
+ private val settings = List(patternCount.toInt()) { mutableMapOf() }
+
+ private val assertions = List(patternCount.toInt()) {
+ mutableMapOf>()
+ }
+
+ /**
+ * The capture names used in the query.
+ *
+ * @since 0.25.0
+ */
+ actual val captureNames = List(ts_query_capture_count(self).convert()) {
+ memScoped {
+ val length = alloc()
+ val name = ts_query_capture_name_for_id(self, it.convert(), length.ptr)
+ if (name == null || length.value == 0U)
+ error("Failed to get capture name at index $it")
+ name.toKString()
}
- val stringValues = List(ts_query_string_count(self).convert()) {
- memScoped {
- val length = alloc()
- val value = ts_query_string_value_for_id(self, it.convert(), length.ptr)
- if (value == null || length.value == 0U)
- error("Failed to get string value at index $it")
- value.toKString()
- }
+ }
+
+ /**
+ * The string literals used in the query.
+ *
+ * @since 0.25.0
+ */
+ actual val stringValues = List(ts_query_string_count(self).convert()) {
+ memScoped {
+ val length = alloc()
+ val value = ts_query_string_value_for_id(self, it.convert(), length.ptr)
+ if (value == null || length.value == 0U)
+ error("Failed to get string value at index $it")
+ value.toKString()
}
+ }
+ init {
for (i in 0U.. 0U) { "The match limit cannot be 0" }
- ts_query_cursor_set_match_limit(cursor, value)
- }
-
- /**
- * The maximum start depth for the query.
- *
- * This prevents cursors from exploring children nodes at a certain depth.
- * Note that if a pattern includes many children, then they will still be checked.
- *
- * Default: `UInt.MAX_VALUE`
- */
- actual var maxStartDepth: UInt = UInt.MAX_VALUE
- set(value) {
- ts_query_cursor_set_max_start_depth(cursor, value)
- field = value
- }
-
- /**
- * The range of bytes in which the query will be executed.
- *
- * Default: `UInt.MIN_VALUE..UInt.MAX_VALUE`
- */
- actual var byteRange: UIntRange = UInt.MIN_VALUE..UInt.MAX_VALUE
- set(value) {
- ts_query_cursor_set_byte_range(cursor, value.first, value.last)
- field = value
- }
-
- /**
- * The range of points in which the query will be executed.
- *
- * Default: `Point.MIN..Point.MAX`
- */
- actual var pointRange: ClosedRange = Point.MIN..Point.MAX
- set(value) {
- val start = cValue { from(value.start) }
- val end = cValue { from(value.endInclusive) }
- ts_query_cursor_set_point_range(cursor, start, end)
- field = value
- }
-
- /**
- * Check if the query exceeded its maximum number of
- * in-progress matches during its last execution.
- */
- actual val didExceedMatchLimit: Boolean
- get() = ts_query_cursor_did_exceed_match_limit(cursor)
-
- /**
- * Iterate over all the matches in the order that they were found.
- *
- * #### Example
- *
- * ```kotlin
- * query.matches(tree.rootNode) {
- * if (name != "ieq?") return@matches true
- * val node = it[(args[0] as QueryPredicateArg.Capture).value].first()
- * val value = (args[1] as QueryPredicateArg.Literal).value
- * value.equals(node.text()?.toString(), ignoreCase = true)
- * }
- * ```
- *
- * @param node The node that the query will run on.
- * @param predicate A function that handles custom predicates.
- */
- @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
- actual fun matches(
- node: Node,
- predicate: QueryPredicate.(QueryMatch) -> Boolean = { true }
- ): Sequence {
- ts_query_cursor_exec(cursor, self, node.self)
- return sequence {
- memScoped {
- val match = alloc()
- while (ts_query_cursor_next_match(cursor, match.ptr)) {
- match.convert(node.tree, predicate)?.let { yield(it) }
- }
- }
- }
- }
-
- /**
- * Iterate over all the individual captures in the order that they appear.
- *
- * This is useful if you don't care about _which_ pattern matched.
- *
- * @param node The node that the query will run on.
- * @param predicate A function that handles custom predicates.
- */
- @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
- actual fun captures(
- node: Node,
- predicate: QueryPredicate.(QueryMatch) -> Boolean = { true }
- ): Sequence> {
- ts_query_cursor_exec(cursor, self, node.self)
- return sequence {
- memScoped {
- val match = alloc()
- val index = alloc()
- while (ts_query_cursor_next_capture(cursor, match.ptr, index.ptr)) {
- match.convert(node.tree, predicate)?.let { yield(index.value to it) }
- }
- }
- }
- }
+ actual operator fun invoke(node: Node, progressCallback: QueryProgressCallback?) =
+ QueryCursor(this, node, progressCallback)
/**
* Get the property settings for the given pattern index.
@@ -535,13 +352,8 @@ actual class Query @Throws(QueryError::class) actual constructor(
* This prevents the capture from being returned in matches,
* and also avoids most resource usage associated with recording
* the capture. Currently, there is no way to undo this.
- *
- * @throws [NoSuchElementException] If the capture does not exist.
*/
- @Throws(NoSuchElementException::class)
actual fun disableCapture(name: String) {
- if (!captureNames.remove(name))
- throw NoSuchElementException("Capture @$name does not exist")
ts_query_disable_capture(self, name, name.length.convert())
}
@@ -617,25 +429,65 @@ actual class Query @Throws(QueryError::class) actual constructor(
override fun toString() = "Query(language=$language, source=$source)"
- private fun TSQueryMatch.convert(
- tree: Tree,
- predicate: QueryPredicate.(QueryMatch) -> Boolean
- ): QueryMatch? {
- val index = pattern_index.convert()
- val captures = (UShort.MIN_VALUE..()]
- QueryCapture(
- Node(c.node.readValue(), tree),
- this@Query.captureNames[c.index]
+ private companion object {
+ private fun init(language: Language, source: String) = memScoped {
+ val errorOffset = alloc()
+ val errorType = alloc()
+ val query = ts_query_new(
+ language.self,
+ source,
+ source.length.convert(),
+ errorOffset.ptr,
+ errorType.ptr
)
- }
- return QueryMatch(index, captures).takeIf { match ->
- tree.text() == null ||
- predicates[index].all {
- if (it !is QueryPredicate.Generic) it(match) else predicate(it, match)
+ if (query != null)
+ return@memScoped query
+
+ var start = 0U
+ var row = 0U
+ val offset = errorOffset.value
+ for (line in source.splitToSequence('\n')) {
+ val lineEnd = start + line.length.toUInt() + 1U
+ if (lineEnd > offset) break
+ start = lineEnd
+ row += 1U
+ }
+ val column = offset - start
+
+ val exception = when (errorType.value) {
+ TSQueryError.TSQueryErrorSyntax -> {
+ if (offset < source.length.toUInt()) {
+ QueryError.Syntax(row.toLong(), column.toLong())
+ } else {
+ QueryError.Syntax(-1, -1)
+ }
+ }
+ TSQueryError.TSQueryErrorCapture -> {
+ val suffix = source.subSequence(offset.toInt(), source.length)
+ val end = suffix.indexOfFirst { !kts_is_valid_predicate_char(it.code) }
+ val error = suffix.subSequence(0, end.takeIf { it > -1 } ?: suffix.length)
+ QueryError.Capture(row, column, error.toString())
}
+ TSQueryError.TSQueryErrorNodeType -> {
+ val suffix = source.subSequence(offset.toInt(), source.length)
+ val end = suffix.indexOfFirst { !kts_is_valid_identifier_char(it.code) }
+ val error = suffix.subSequence(0, end.takeIf { it > -1 } ?: suffix.length)
+ QueryError.NodeType(row, column, error.toString())
+ }
+ TSQueryError.TSQueryErrorField -> {
+ val suffix = source.subSequence(offset.toInt(), source.length)
+ val end = suffix.indexOfFirst { !kts_is_valid_identifier_char(it.code) }
+ val error = suffix.subSequence(0, end.takeIf { it > -1 } ?: suffix.length)
+ QueryError.Field(row, column, error.toString())
+ }
+ TSQueryError.TSQueryErrorStructure -> QueryError.Structure(row, column)
+ // language errors are handled in the Language class
+ else -> IllegalStateException("Unexpected query error")
+ }
+ throw exception
}
- }
- private inline operator fun List.get(index: UInt) = get(index.toInt())
+ @Suppress("NOTHING_TO_INLINE")
+ private inline operator fun List.get(index: UInt) = get(index.toInt())
+ }
}
diff --git a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt
new file mode 100644
index 0000000..34c06de
--- /dev/null
+++ b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/QueryCursor.kt
@@ -0,0 +1,200 @@
+package io.github.treesitter.ktreesitter
+
+import io.github.treesitter.ktreesitter.internal.*
+import kotlin.experimental.ExperimentalNativeApi
+import kotlin.native.ref.createCleaner
+import kotlinx.cinterop.*
+
+/**
+ * A class that is used for executing a query.
+ *
+ * @since 0.25.0
+ */
+@OptIn(ExperimentalForeignApi::class)
+actual class QueryCursor internal constructor(
+ private val query: Query,
+ private val node: Node,
+ progressCallback: QueryProgressCallback? = null
+) {
+ internal val self = ts_query_cursor_new()!!
+
+ init {
+ if (progressCallback == null) {
+ ts_query_cursor_exec(self, query.self, node.self)
+ } else {
+ val progressRef = StableRef.create(progressCallback)
+ val options = cValue {
+ payload = progressRef.asCPointer()
+ progress_callback = staticCFunction { state ->
+ val callback = state!!.pointed.payload!!
+ .asStableRef().get()
+ callback(state.pointed.current_byte_offset)
+ }
+ }
+ ts_query_cursor_exec_with_options(self, query.self, node.self, options)
+ progressRef.dispose()
+ }
+ }
+
+ @Suppress("unused")
+ @OptIn(ExperimentalNativeApi::class)
+ private val cleaner = createCleaner(self, ::ts_query_cursor_delete)
+
+ /**
+ * The maximum duration in microseconds that query
+ * execution should be allowed to take before halting.
+ *
+ * Default: `0`
+ *
+ * @since 0.23.0
+ */
+ @Deprecated("Use the progressCallback in Query.invoke()")
+ actual var timeoutMicros: ULong
+ get() = ts_query_cursor_timeout_micros(self)
+ set(value) {
+ ts_query_cursor_set_timeout_micros(self, value)
+ }
+
+ /**
+ * The maximum number of in-progress matches.
+ *
+ * Default: `UInt.MAX_VALUE`
+ *
+ * @throws [IllegalArgumentException] If the match limit is set to `0`.
+ */
+ actual var matchLimit: UInt
+ get() = ts_query_cursor_match_limit(self)
+ set(value) {
+ require(value > 0U) { "The match limit cannot be 0" }
+ ts_query_cursor_set_match_limit(self, value)
+ }
+
+ /**
+ * The maximum start depth for the query.
+ *
+ * This prevents cursors from exploring children nodes at a certain depth.
+ * Note that if a pattern includes many children, then they will still be checked.
+ *
+ * Default: `UInt.MAX_VALUE`
+ */
+ actual var maxStartDepth: UInt = UInt.MAX_VALUE
+ set(value) {
+ ts_query_cursor_set_max_start_depth(self, value)
+ field = value
+ }
+
+ /**
+ * The range of bytes in which the query will be executed.
+ *
+ * The query cursor will return matches that intersect with
+ * the given range. This means that a match may be returned
+ * even if some of its captures fall outside the specified range,
+ * as long as at least part of the match overlaps with the range.
+ *
+ * Default: `UInt.MIN_VALUE..UInt.MAX_VALUE`
+ *
+ * @throws [IllegalArgumentException] If set to an invalid range.
+ */
+ actual var byteRange: UIntRange = UInt.MIN_VALUE..UInt.MAX_VALUE
+ set(value) {
+ require(ts_query_cursor_set_byte_range(self, value.first, value.last)) {
+ "Invalid byte range: [${value.first}, ${value.last}]"
+ }
+ field = value
+ }
+
+ /**
+ * The range of points in which the query will be executed.
+ *
+ * The query cursor will return matches that intersect with
+ * the given range. This means that a match may be returned
+ * even if some of its captures fall outside the specified range,
+ * as long as at least part of the match overlaps with the range.
+ *
+ * Default: `Point.MIN..Point.MAX`
+ *
+ * @throws [IllegalArgumentException] If set to an invalid range.
+ */
+ actual var pointRange: ClosedRange = Point.MIN..Point.MAX
+ set(value) {
+ val start = cValue { from(value.start) }
+ val end = cValue { from(value.endInclusive) }
+ require(ts_query_cursor_set_point_range(self, start, end)) {
+ "Invalid point range: [${value.start}, ${value.endInclusive}]"
+ }
+ field = value
+ }
+
+ /**
+ * Check if the query exceeded its maximum number of
+ * in-progress matches during its last execution.
+ *
+ * @see matchLimit
+ */
+ actual val didExceedMatchLimit: Boolean
+ get() = ts_query_cursor_did_exceed_match_limit(self)
+
+ /**
+ * Iterate over all the matches in the order that they were found.
+ *
+ * #### Example
+ *
+ * ```kotlin
+ * query(tree.rootNode).matches {
+ * if (name != "ieq?") return@matches true
+ * val node = it[(args[0] as QueryPredicateArg.Capture).value].first()
+ * val value = (args[1] as QueryPredicateArg.Literal).value
+ * value.equals(node.text()?.toString(), ignoreCase = true)
+ * }
+ * ```
+ *
+ * @param predicate A function that handles custom predicates.
+ */
+ actual fun matches(predicate: QueryPredicate.(QueryMatch) -> Boolean) = sequence {
+ memScoped {
+ val match = alloc()
+ while (ts_query_cursor_next_match(self, match.ptr)) {
+ match.convert(predicate)?.let { yield(it) }
+ }
+ }
+ }
+
+ /**
+ * Iterate over all the individual captures in the order that they appear.
+ *
+ * This is useful if you don't care about _which_ pattern matched.
+ *
+ * @param predicate A function that handles custom predicates.
+ */
+ actual fun captures(predicate: QueryPredicate.(QueryMatch) -> Boolean) =
+ sequence> {
+ memScoped {
+ val match = alloc()
+ val index = alloc()
+ while (ts_query_cursor_next_capture(self, match.ptr, index.ptr)) {
+ match.convert(predicate)?.let { yield(index.value to it) }
+ }
+ }
+ }
+
+ override fun toString() = "QueryCursor(query=$query, node=$node)"
+
+ private fun TSQueryMatch.convert(
+ predicate: QueryPredicate.(QueryMatch) -> Boolean
+ ): QueryMatch? {
+ val index = pattern_index.convert()
+ val captures = (UShort.MIN_VALUE..()]
+ QueryCapture(
+ Node(c.node.readValue(), node.tree),
+ query.captureNames[c.index.toInt()]
+ )
+ }
+ return QueryMatch(index, captures).takeIf { match ->
+ node.tree.text() == null ||
+ query.predicates[index.toInt()].all {
+ if (it !is QueryPredicate.Generic) it(match) else predicate(it, match)
+ }
+ }
+ }
+}
diff --git a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Utils.kt b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Utils.kt
index 44e3fc7..79d640b 100644
--- a/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Utils.kt
+++ b/ktreesitter/src/nativeMain/kotlin/io/github/treesitter/ktreesitter/Utils.kt
@@ -1,3 +1,5 @@
+@file:Suppress("NOTHING_TO_INLINE")
+
package io.github.treesitter.ktreesitter
import io.github.treesitter.ktreesitter.internal.*
diff --git a/languages/java/build.gradle.kts b/languages/java/build.gradle.kts
index e90ae26..3243130 100644
--- a/languages/java/build.gradle.kts
+++ b/languages/java/build.gradle.kts
@@ -2,12 +2,23 @@ import java.io.OutputStream.nullOutputStream
import org.gradle.internal.os.OperatingSystem
import org.gradle.kotlin.dsl.support.useToRun
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
-import org.jetbrains.kotlin.konan.target.PlatformManager
inline val File.unixPath: String
get() = if (!os.isWindows) path else path.replace("\\", "/")
+fun KotlinNativeTarget.treesitterJava() {
+ compilations.configureEach {
+ cinterops.create("treesitterJava") {
+ definitionFile.set(generateTask.interopFile)
+ includeDirs.allHeaders(grammarDir.resolve("bindings/c"))
+ extraOpts("-libraryPath", libsDir.dir(konanTarget.name))
+ tasks.getByName(interopProcessingTaskName).mustRunAfter(generateTask)
+ }
+ }
+}
+
val os: OperatingSystem = OperatingSystem.current()
val libsDir = layout.buildDirectory.get().dir("libs")
val grammarDir = projectDir.resolve("tree-sitter-java")
@@ -28,10 +39,6 @@ grammar {
grammarName = project.name
className = "TreeSitterJava"
packageName = "io.github.treesitter.ktreesitter.java"
- files = arrayOf(
- // grammarDir.resolve("src/scanner.c"),
- grammarDir.resolve("src/parser.c")
- )
}
val generateTask = tasks.generateGrammarFiles.get()
@@ -44,29 +51,15 @@ kotlin {
publishLibraryVariants("release")
}
- when {
- os.isLinux -> listOf(linuxX64(), linuxArm64())
- os.isWindows -> listOf(mingwX64())
- os.isMacOsX -> listOf(
- macosArm64(),
- macosX64(),
- iosArm64(),
- iosSimulatorArm64()
- )
- else -> {
- val arch = System.getProperty("os.arch")
- throw GradleException("Unsupported platform: $os ($arch)")
- }
- }.forEach { target ->
- target.compilations.configureEach {
- cinterops.create(grammar.interopName.get()) {
- defFileProperty.set(generateTask.interopFile.asFile)
- includeDirs.allHeaders(grammarDir.resolve("bindings/c"))
- extraOpts("-libraryPath", libsDir.dir(konanTarget.name))
- tasks.getByName(interopProcessingTaskName).mustRunAfter(generateTask)
- }
- }
- }
+ linuxX64 { treesitterJava() }
+ linuxArm64 { treesitterJava() }
+ mingwX64 { treesitterJava() }
+ macosArm64 { treesitterJava() }
+ macosX64 { treesitterJava() }
+ iosArm64 { treesitterJava() }
+ iosSimulatorArm64 { treesitterJava() }
+
+ applyDefaultHierarchyTemplate()
jvmToolchain(17)
@@ -102,7 +95,6 @@ android {
defaultConfig {
minSdk = (property("sdk.version.min") as String).toInt()
ndk {
- moduleName = grammar.libraryName.get()
//noinspection ChromeOsAbiSupport
abiFilters += setOf("x86_64", "arm64-v8a", "armeabi-v7a")
}
@@ -121,26 +113,28 @@ android {
}
}
+// TODO: replace with cmake
+@Suppress("DEPRECATION")
tasks.withType().configureEach {
if (name.startsWith("cinteropTest")) return@configureEach
- val grammarFiles = grammar.files.get()
+ val srcDir = grammarDir.resolve("src")
+ val grammarFiles =
+ if (!srcDir.resolve("scanner.c").isFile) arrayOf(srcDir.resolve("parser.c"))
+ else arrayOf(srcDir.resolve("parser.c"), srcDir.resolve("scanner.c"))
val grammarName = grammar.grammarName.get()
val runKonan = File(konanHome.get()).resolve("bin")
.resolve(if (os.isWindows) "run_konan.bat" else "run_konan").path
val libFile = libsDir.dir(konanTarget.name).file("libtree-sitter-$grammarName.a").asFile
val objectFiles = grammarFiles.map {
- grammarDir.resolve(it.nameWithoutExtension + ".o").path
+ srcDir.resolve(it.nameWithoutExtension + ".o").path
}.toTypedArray()
- val loader = PlatformManager(konanHome.get(), false, konanDataDir.orNull).loader(konanTarget)
doFirst {
- if (!File(loader.absoluteTargetToolchain).isDirectory) loader.downloadDependencies()
-
val argsFile = File.createTempFile("args", null)
argsFile.deleteOnExit()
argsFile.writer().useToRun {
- write("-I" + grammarDir.resolve("src").unixPath + "\n")
+ write("-I" + srcDir.unixPath + "\n")
write("-DTREE_SITTER_HIDE_SYMBOLS\n")
write("-fvisibility=hidden\n")
write("-std=c11\n")
diff --git a/languages/java/tree-sitter-java b/languages/java/tree-sitter-java
index 94703d5..a7db522 160000
--- a/languages/java/tree-sitter-java
+++ b/languages/java/tree-sitter-java
@@ -1 +1 @@
-Subproject commit 94703d5a6bed02b98e438d7cad1136c01a60ba2c
+Subproject commit a7db5227ec40fcfe94489559d8c9bc7c8181e25a
diff --git a/tree-sitter b/tree-sitter
index 5e8760b..4fcf78c 160000
--- a/tree-sitter
+++ b/tree-sitter
@@ -1 +1 @@
-Subproject commit 5e8760bf462ce7b19b3d2396d5b7860f3906a297
+Subproject commit 4fcf78cfec32532b5e74e21cbb135b25127444eb