diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml new file mode 100644 index 000000000..966ee5d5d --- /dev/null +++ b/.github/actions/setup-java/action.yml @@ -0,0 +1,12 @@ +name: Setup Java +description: Installs needed jdk version +runs: + using: composite + steps: + - uses: actions/setup-java@v4 + with: + distribution: adopt + java-version: | + 22 + 17 + cache: gradle diff --git a/.github/actions/setup-jextract/action.yml b/.github/actions/setup-jextract/action.yml new file mode 100644 index 000000000..95a2910e3 --- /dev/null +++ b/.github/actions/setup-jextract/action.yml @@ -0,0 +1,9 @@ +name: Setup JExtract +description: Installs a jextract +runs: + using: composite + steps: + - uses: oracle-actions/setup-java@v1 + with: + website: jdk.java.net + release: jextract diff --git a/.github/actions/setup-zig/action.yml b/.github/actions/setup-zig/action.yml new file mode 100644 index 000000000..b370b634f --- /dev/null +++ b/.github/actions/setup-zig/action.yml @@ -0,0 +1,9 @@ +name: Setup Zig +description: Installs a zig compiler +runs: + using: composite + steps: + - uses: goto-bus-stop/setup-zig@v2 + with: + version: 0.13.0 + diff --git a/.github/actions/update-ts-languages/action.yml b/.github/actions/update-ts-languages/action.yml new file mode 100644 index 000000000..b85e07255 --- /dev/null +++ b/.github/actions/update-ts-languages/action.yml @@ -0,0 +1,10 @@ +name: Update TS Languages +description: Runs scripts to update treesitter and its languages +runs: + using: composite + steps: + - name: Update TS Languages + shell: bash + run: | + ./scripts/generate-ts.sh -jz + ./scripts/generate-languages.sh -jz diff --git a/.github/workflows/ci-native.yml b/.github/workflows/ci-native.yml index 8213d543e..d1ca89f04 100644 --- a/.github/workflows/ci-native.yml +++ b/.github/workflows/ci-native.yml @@ -5,30 +5,30 @@ on: jobs: build: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - nickname: linux jdk17 - java: 17 - os: ubuntu-latest - - nickname: macos jdk17 - java: 17 - os: macos-latest - - nickname: windows jdk17 - java: 17 - os: windows-latest - name: CI Build ${{ matrix.nickname }} + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 - with: - distribution: adopt - java-version: | - 22 - 17 - cache: gradle + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-zig + - uses: ./.github/actions/setup-jextract + - uses: ./.github/actions/setup-java + - uses: ./.github/actions/update-ts-languages - name: Build - run: ./gradlew build - + run: ./gradlew build -PshellIncludeTags=treesitter + - name: Publish Local Repo + run: ./gradlew publishMavenJavaPublicationToLocalRepository + - name: Upload Local Repo + uses: actions/upload-artifact@v4 + with: + retention-days: 1 + name: localrepo + path: | + build/publications/repos + - name: Upload Build Logs + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + retention-days: 1 + name: buildlogs + path: | + */build/reports + */*/build/reports diff --git a/.gitignore b/.gitignore index d87cc5420..6f06788fb 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,14 @@ spring-shell.log shell.log shell.log.*.gz shell.log.*.tmp +shell-*.log +shell-*.log.*.gz +shell-*.log.*.tmp + +# Native Libs +*.so +*.dll +*.jnilib # Visual Studio Code .vscode/* diff --git a/.vscode/launch.json b/.vscode/launch.json index f1b575df0..969c495d8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -109,6 +109,14 @@ "console": "externalTerminal", "mainClass": "org.springframework.shell.samples.catalog.SpringShellApplication", "projectName": "spring-shell-sample-catalog" + }, + { + "type": "java", + "name": "ffm interactive", + "request": "launch", + "mainClass": "org.springframework.shell.samples.ffm.SpringShellApplication", + "projectName": "spring-shell-sample-ffm", + "vmArgs": "--enable-native-access=ALL-UNNAMED" } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 0c8777c18..09da40ac9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,9 @@ "org.springframework", "#" ], + "java.project.resourceFilters": [ + "sample" + ], "java.checkstyle.configuration": "https://raw.githubusercontent.com/spring-cloud/spring-cloud-dataflow-build/main/spring-cloud-dataflow-build-tools/src/main/resources/checkstyle.xml", "java.checkstyle.properties": { "checkstyle.suppressions.file": "https://raw.githubusercontent.com/spring-cloud/spring-cloud-dataflow-build/main/spring-cloud-dataflow-build-tools/src/checkstyle/checkstyle-suppressions.xml", diff --git a/_templates/init/tslanguage/gradle-build.txt b/_templates/init/tslanguage/gradle-build.txt new file mode 100644 index 000000000..58c513386 --- /dev/null +++ b/_templates/init/tslanguage/gradle-build.txt @@ -0,0 +1,16 @@ +--- +force: true +to: spring-shell-treesitter-languages/spring-shell-treesitter-language-<%= language %>/spring-shell-treesitter-language-<%= language %>.gradle +--- +plugins { + id 'org.springframework.shell.module' + id 'org.springframework.shell.toolchain' +} + +description = 'Spring Shell Treesitter <%= h.changeCase.pascal(language) %>' + +dependencies { + management platform(project(":spring-shell-management")) + implementation project(':spring-shell-treesitter') + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} diff --git a/_templates/init/tslanguage/main-language-class.txt b/_templates/init/tslanguage/main-language-class.txt new file mode 100644 index 000000000..81bd799e0 --- /dev/null +++ b/_templates/init/tslanguage/main-language-class.txt @@ -0,0 +1,56 @@ +--- +force: true +to: spring-shell-treesitter-languages/spring-shell-treesitter-language-<%= language %>/src/main/java/org/springframework/shell/treesitter/language/<%= language %>/TreeSitterLanguage<%= h.changeCase.pascal(language) %>.java +--- +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.language.<%= language %>; + +import java.lang.foreign.MemorySegment; +import java.util.List; + +import org.springframework.shell.treesitter.AbstractTreeSitterLanguage; +import org.springframework.shell.treesitter.language.<%= language %>.ts.TreeSitter<%= h.changeCase.pascal(language) %>; + +public class TreeSitterLanguage<%= h.changeCase.pascal(language) %> extends AbstractTreeSitterLanguage { + + @Override + public boolean supports(String languageName) { + return "<%= language %>".equals(languageName); + } + + @Override + public List supportedLanguages() { + return List.of("<%= language %>"); + } + + @Override + public TreeSitterLanguage<%= h.changeCase.pascal(language) %> language() { + return this; + } + + @Override + public String highlightQuery() { + return resourceAsString(resourceLoader.getResource("classpath:org/springframework/shell/treesitter/queries/<%= language %>/highlights.scm")); + } + + @Override + public MemorySegment initInternal() { + MemorySegment <%= language %> = TreeSitter<%= h.changeCase.pascal(language) %>.tree_sitter_<%= language %>(); + return <%= language %>; + } + +} diff --git a/_templates/init/tslanguage/test-language-class.txt b/_templates/init/tslanguage/test-language-class.txt new file mode 100644 index 000000000..d8a720010 --- /dev/null +++ b/_templates/init/tslanguage/test-language-class.txt @@ -0,0 +1,42 @@ +--- +force: true +to: spring-shell-treesitter-languages/spring-shell-treesitter-language-<%= language %>/src/test/java/org/springframework/shell/treesitter/language/<%= language %>/TreeSitterLanguage<%= h.changeCase.pascal(language) %>Tests.java +--- +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.language.<%= language %>; + +import java.lang.foreign.MemorySegment; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.TreeSitterNativeLoader; +import org.springframework.shell.treesitter.language.<%= language %>.ts.TreeSitter<%= h.changeCase.pascal(language) %>; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TreeSitterLanguage<%= h.changeCase.pascal(language) %>Tests { + + @Test + @Tag("treesitter") + void languageLoads() { + TreeSitterNativeLoader.initializeLanguage("<%= language %>"); + MemorySegment segment = TreeSitter<%= h.changeCase.pascal(language) %>.tree_sitter_<%= language %>(); + assertThat(segment).isNotNull(); + } + +} \ No newline at end of file diff --git a/_templates/init/tslanguage/treesitter-factories.txt b/_templates/init/tslanguage/treesitter-factories.txt new file mode 100644 index 000000000..00ea12cbc --- /dev/null +++ b/_templates/init/tslanguage/treesitter-factories.txt @@ -0,0 +1,6 @@ +--- +force: true +to: spring-shell-treesitter-languages/spring-shell-treesitter-language-<%= language %>/src/main/resources/META-INF/spring/treesitter.factories +--- +org.springframework.shell.treesitter.TreeSitterLanguageProvider=\ +org.springframework.shell.treesitter.language.<%= language %>.TreeSitterLanguage<%= h.changeCase.pascal(language) %> diff --git a/buildSrc/src/main/java/org/springframework/shell/gradle/JavaConventions.java b/buildSrc/src/main/java/org/springframework/shell/gradle/JavaConventions.java index b895aa8eb..1b253d3f0 100644 --- a/buildSrc/src/main/java/org/springframework/shell/gradle/JavaConventions.java +++ b/buildSrc/src/main/java/org/springframework/shell/gradle/JavaConventions.java @@ -41,7 +41,7 @@ class JavaConventions { private static final String SOURCE_AND_TARGET_COMPATIBILITY = "17"; private static final String INCLUDE_TAGS = "shellIncludeTags"; private static final String EXCLUDE_TAGS = "shellExcludeTags"; - private static final String[] DEFAULT_EXCLUDE_TAGS = new String[] { }; + private static final String[] DEFAULT_EXCLUDE_TAGS = new String[] { "treesitter" }; void apply(Project project) { project.getPlugins().withType(JavaBasePlugin.class, java -> { diff --git a/scripts/generate-languages.sh b/scripts/generate-languages.sh new file mode 100755 index 000000000..183551fa7 --- /dev/null +++ b/scripts/generate-languages.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +find_basedir() { + local basedir=$(cd -P -- "$(dirname -- "$0")" && cd .. && pwd -P) + echo "${basedir}" +} + +dojextract='false' +dozig='false' + +print_usage() { + echo "Usage: generate-languages.sh [-j] [-z]" +} + +while getopts 'jz' flag; do + case "${flag}" in + j) dojextract='true' ;; + z) dozig='true' ;; + *) print_usage + exit 1 ;; + esac +done + +TMPDIR=/tmp/spring-shell-tslanguages +rm -fr $TMPDIR + +VALUES=' +tree-sitter,tree-sitter-java,v0.21.0,java +tree-sitter,tree-sitter-json,v0.21.0,json +tree-sitter-grammars,tree-sitter-yaml,v0.6.1,yaml +' + +# tree-sitter,tree-sitter-python,v0.21.0,python +# tree-sitter,tree-sitter-php,v0.22.8,php +# tree-sitter,tree-sitter-cpp,v0.22.3,cpp +# tree-sitter,tree-sitter-ruby,v0.21.0,ruby +# tree-sitter,tree-sitter-c,v0.21.4,c +# tree-sitter,tree-sitter-scala,v0.22.5,scala +# tree-sitter,tree-sitter-go,v0.21.2,go +# tree-sitter,tree-sitter-rust,v0.21.2,rust +# tree-sitter,tree-sitter-javascript,v0.21.4,javascript +# tree-sitter,tree-sitter-html,v0.20.4,html +# tree-sitter,tree-sitter-css,v0.21.1,css +# tree-sitter,tree-sitter-julia,v0.22.6,julia +# tree-sitter,tree-sitter-typescript,v0.21.2,typescript +# tree-sitter,tree-sitter-jsdoc,v0.21.0,jsdoc +# tree-sitter,tree-sitter-regex,v1.0.0,regex +# tree-sitter,tree-sitter-ocaml,v0.22.0,ocaml +# tree-sitter,tree-sitter-c-scharp,v0.21.3,csharp +# tree-sitter,tree-sitter-bash,v0.21.0,bash +# tree-sitter-grammars,tree-sitter-markdown,v0.2.3,markdown +# tree-sitter-grammars,tree-sitter-xml,v0.6.4,xml +# tree-sitter-grammars,tree-sitter-lua,v0.1.0,lua + +export PROJECTBASEDIR=$(find_basedir) + +for VALUE in $VALUES; + do + GHOWNER=$(echo $VALUE | cut -f1 -d,) + GHREPO=$(echo $VALUE | cut -f2 -d,) + TAG=$(echo $VALUE | cut -f3 -d,) + LANGUAGEID=$(echo $VALUE | cut -f4 -d,) + LANGUAGENAME="${LANGUAGEID^}" + REPOPATH=$TMPDIR/$GHOWNER/$GHREPO + TARGETMODULEPATH=spring-shell-treesitter-languages/spring-shell-treesitter-language-$LANGUAGEID + git clone --depth 1 -b $TAG https://github.com/$GHOWNER/$GHREPO.git $REPOPATH + + if [ "$dojextract" == "true" ]; then + npx hygen init tslanguage --language $LANGUAGEID + mkdir -p $TARGETMODULEPATH/src/ts + cp $REPOPATH/bindings/c/tree-sitter-$LANGUAGEID.h $TARGETMODULEPATH/src/ts/ + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/queries/$LANGUAGEID + cp $REPOPATH/queries/highlights.scm $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/queries/$LANGUAGEID/ + jextract --header-class-name TreeSitter$LANGUAGENAME --output $TARGETMODULEPATH/src/main/java -t org.springframework.shell.treesitter.language.$LANGUAGEID.ts $TARGETMODULEPATH/src/ts/tree-sitter-$LANGUAGEID.h + fi + + if [ "$dozig" == "true" ]; then + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/linux/x86_64 + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/windows/x86_64 + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/mac/x86_64 + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/mac/arm64 + ZIGFILES=$REPOPATH/src/parser.c + if [ -f $REPOPATH/src/scanner.c ]; then + ZIGFILES="$ZIGFILES $REPOPATH/src/scanner.c" + fi + zig cc -g0 -O2 -shared -target x86_64-linux-gnu -std=c11 -I $REPOPATH/src -o $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/linux/x86_64/libtree-sitter-$LANGUAGEID.so $ZIGFILES + zig cc -g0 -O2 -shared -target x86_64-windows -std=c11 -I $REPOPATH/src -o $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/windows/x86_64/tree-sitter-$LANGUAGEID.dll $ZIGFILES + rm $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/windows/x86_64/*.pdb + rm $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/windows/x86_64/*.lib + zig cc -g0 -O2 -shared -target x86_64-macos -std=c11 -I $REPOPATH/src -o $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/mac/x86_64/libtree-sitter-$LANGUAGEID.jnilib $ZIGFILES + zig cc -g0 -O2 -shared -target aarch64-macos -std=c11 -I $REPOPATH/src -o $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/mac/arm64/libtree-sitter-$LANGUAGEID.jnilib $ZIGFILES + fi + +done; + diff --git a/scripts/generate-ts.sh b/scripts/generate-ts.sh new file mode 100755 index 000000000..d403081a7 --- /dev/null +++ b/scripts/generate-ts.sh @@ -0,0 +1,230 @@ +#!/bin/bash + +find_basedir() { + local basedir=$(cd -P -- "$(dirname -- "$0")" && cd .. && pwd -P) + echo "${basedir}" +} + +dojextract='false' +dozig='false' + +print_usage() { + echo "Usage: generate-ts.sh [-j] [-z]" +} + +while getopts 'jz' flag; do + case "${flag}" in + j) dojextract='true' ;; + z) dozig='true' ;; + *) print_usage + exit 1 ;; + esac +done + +TMPDIR=/tmp/spring-shell-ts +rm -fr $TMPDIR + +GHOWNER=tree-sitter +GHREPO=tree-sitter +TAG=v0.23.0 +REPOPATH=$TMPDIR/$GHOWNER/$GHREPO +TARGETMODULEPATH=spring-shell-treesitter + +git clone --depth 1 -b $TAG https://github.com/$GHOWNER/$GHREPO.git $REPOPATH +mkdir -p $TARGETMODULEPATH/src/ts +cp $REPOPATH/lib/include/tree_sitter/api.h $TARGETMODULEPATH/src/ts/ + +if [ "$dojextract" == "true" ]; then + rm $TARGETMODULEPATH/src/main/java/org/springframework/shell/treesitter/ts/*.java + jextract \ + --header-class-name TreeSitter \ + --include-struct TSInput \ + --include-struct TSInputEdit \ + --include-struct TSLogger \ + --include-struct TSNode \ + --include-struct TSPoint \ + --include-struct TSQueryCapture \ + --include-struct TSQueryMatch \ + --include-struct TSQueryPredicateStep \ + --include-struct TSQueryPredicateStepType \ + --include-struct TSRange \ + --include-struct TSTreeCursor \ + --include-function free \ + --include-function ts_language_copy \ + --include-function ts_language_delete \ + --include-function ts_language_field_count \ + --include-function ts_language_field_id_for_name \ + --include-function ts_language_field_name_for_id \ + --include-function ts_language_next_state \ + --include-function ts_language_state_count \ + --include-function ts_language_symbol_count \ + --include-function ts_language_symbol_for_name \ + --include-function ts_language_symbol_name \ + --include-function ts_language_symbol_type \ + --include-function ts_language_version \ + --include-function ts_lookahead_iterator_current_symbol \ + --include-function ts_lookahead_iterator_current_symbol_name \ + --include-function ts_lookahead_iterator_delete \ + --include-function ts_lookahead_iterator_language \ + --include-function ts_lookahead_iterator_new \ + --include-function ts_lookahead_iterator_next \ + --include-function ts_lookahead_iterator_reset \ + --include-function ts_lookahead_iterator_reset_state \ + --include-function ts_node_child \ + --include-function ts_node_child_by_field_id \ + --include-function ts_node_child_by_field_name \ + --include-function ts_node_child_containing_descendant \ + --include-function ts_node_child_count \ + --include-function ts_node_descendant_count \ + --include-function ts_node_descendant_for_byte_range \ + --include-function ts_node_descendant_for_point_range \ + --include-function ts_node_edit \ + --include-function ts_node_end_byte \ + --include-function ts_node_end_point \ + --include-function ts_node_eq \ + --include-function ts_node_field_name_for_child \ + --include-function ts_node_first_child_for_byte \ + --include-function ts_node_first_named_child_for_byte \ + --include-function ts_node_grammar_symbol \ + --include-function ts_node_grammar_type \ + --include-function ts_node_has_changes \ + --include-function ts_node_has_error \ + --include-function ts_node_is_error \ + --include-function ts_node_is_extra \ + --include-function ts_node_is_missing \ + --include-function ts_node_is_named \ + --include-function ts_node_is_null \ + --include-function ts_node_language \ + --include-function ts_node_named_child \ + --include-function ts_node_named_child_count \ + --include-function ts_node_named_descendant_for_byte_range \ + --include-function ts_node_named_descendant_for_point_range \ + --include-function ts_node_next_named_sibling \ + --include-function ts_node_next_parse_state \ + --include-function ts_node_next_sibling \ + --include-function ts_node_parent \ + --include-function ts_node_parse_state \ + --include-function ts_node_prev_named_sibling \ + --include-function ts_node_prev_sibling \ + --include-function ts_node_start_byte \ + --include-function ts_node_start_point \ + --include-function ts_node_string \ + --include-function ts_node_symbol \ + --include-function ts_node_type \ + --include-function ts_parser_cancellation_flag \ + --include-function ts_parser_delete \ + --include-function ts_parser_included_ranges \ + --include-function ts_parser_language \ + --include-function ts_parser_logger \ + --include-function ts_parser_new \ + --include-function ts_parser_parse \ + --include-function ts_parser_parse_string \ + --include-function ts_parser_parse_string_encoding \ + --include-function ts_parser_print_dot_graphs \ + --include-function ts_parser_reset \ + --include-function ts_parser_set_cancellation_flag \ + --include-function ts_parser_set_included_ranges \ + --include-function ts_parser_set_language \ + --include-function ts_parser_set_logger \ + --include-function ts_parser_set_timeout_micros \ + --include-function ts_parser_timeout_micros \ + --include-function ts_query_capture_count \ + --include-function ts_query_capture_name_for_id \ + --include-function ts_query_capture_quantifier_for_id \ + --include-function ts_query_cursor_delete \ + --include-function ts_query_cursor_did_exceed_match_limit \ + --include-function ts_query_cursor_exec \ + --include-function ts_query_cursor_match_limit \ + --include-function ts_query_cursor_new \ + --include-function ts_query_cursor_next_capture \ + --include-function ts_query_cursor_next_match \ + --include-function ts_query_cursor_remove_match \ + --include-function ts_query_cursor_set_byte_range \ + --include-function ts_query_cursor_set_match_limit \ + --include-function ts_query_cursor_set_max_start_depth \ + --include-function ts_query_cursor_set_point_range \ + --include-function ts_query_cursor_set_timeout_micros \ + --include-function ts_query_cursor_timeout_micros \ + --include-function ts_query_delete \ + --include-function ts_query_disable_capture \ + --include-function ts_query_disable_pattern \ + --include-function ts_query_end_byte_for_pattern \ + --include-function ts_query_is_pattern_guaranteed_at_step \ + --include-function ts_query_is_pattern_non_local \ + --include-function ts_query_is_pattern_rooted \ + --include-function ts_query_new \ + --include-function ts_query_pattern_count \ + --include-function ts_query_predicates_for_pattern \ + --include-function ts_query_start_byte_for_pattern \ + --include-function ts_query_string_count \ + --include-function ts_query_string_value_for_id \ + --include-function ts_tree_copy \ + --include-function ts_tree_cursor_copy \ + --include-function ts_tree_cursor_current_depth \ + --include-function ts_tree_cursor_current_descendant_index \ + --include-function ts_tree_cursor_current_field_id \ + --include-function ts_tree_cursor_current_field_name \ + --include-function ts_tree_cursor_current_node \ + --include-function ts_tree_cursor_delete \ + --include-function ts_tree_cursor_goto_descendant \ + --include-function ts_tree_cursor_goto_first_child \ + --include-function ts_tree_cursor_goto_first_child_for_byte \ + --include-function ts_tree_cursor_goto_first_child_for_point \ + --include-function ts_tree_cursor_goto_last_child \ + --include-function ts_tree_cursor_goto_next_sibling \ + --include-function ts_tree_cursor_goto_parent \ + --include-function ts_tree_cursor_goto_previous_sibling \ + --include-function ts_tree_cursor_new \ + --include-function ts_tree_cursor_reset \ + --include-function ts_tree_cursor_reset_to \ + --include-function ts_tree_delete \ + --include-function ts_tree_edit \ + --include-function ts_tree_get_changed_ranges \ + --include-function ts_tree_included_ranges \ + --include-function ts_tree_language \ + --include-function ts_tree_print_dot_graph \ + --include-function ts_tree_root_node \ + --include-function ts_tree_root_node_with_offset \ + --include-constant TREE_SITTER_LANGUAGE_VERSION \ + --include-constant TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION \ + --include-constant TSInputEncodingUTF16 \ + --include-constant TSInputEncodingUTF8 \ + --include-constant TSLogTypeLex \ + --include-constant TSLogTypeParse \ + --include-constant TSQuantifierOne \ + --include-constant TSQuantifierOneOrMore \ + --include-constant TSQuantifierZero \ + --include-constant TSQuantifierZeroOrMore \ + --include-constant TSQuantifierZeroOrOne \ + --include-constant TSQueryErrorCapture \ + --include-constant TSQueryErrorField \ + --include-constant TSQueryErrorLanguage \ + --include-constant TSQueryErrorNodeType \ + --include-constant TSQueryErrorNone \ + --include-constant TSQueryErrorStructure \ + --include-constant TSQueryErrorSyntax \ + --include-constant TSQueryPredicateStepTypeCapture \ + --include-constant TSQueryPredicateStepTypeDone \ + --include-constant TSQueryPredicateStepTypeString \ + --include-constant TSSymbolTypeAnonymous \ + --include-constant TSSymbolTypeAuxiliary \ + --include-constant TSSymbolTypeRegular \ + --output $TARGETMODULEPATH/src/main/java \ + -t org.springframework.shell.treesitter.ts \ + $TARGETMODULEPATH/src/ts/api.h +fi + +if [ "$dozig" == "true" ]; then + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/linux/x86_64 + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/windows/x86_64 + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/mac/x86_64 + mkdir -p $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/mac/arm64 + ZIGFILES=$REPOPATH/lib/src/lib.c + + zig cc -g0 -O2 -shared -target x86_64-linux-gnu -std=c11 -I $REPOPATH/lib/include -I $REPOPATH/lib/src -o $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/linux/x86_64/libtree-sitter.so $ZIGFILES + zig cc -g0 -O2 -shared -target x86_64-windows -std=c11 -I $REPOPATH/lib/include -I $REPOPATH/lib/src -o $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/windows/x86_64/tree-sitter.dll $ZIGFILES + rm $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/windows/x86_64/*.pdb + rm $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/windows/x86_64/*.lib + zig cc -g0 -O2 -shared -target x86_64-macos -std=c11 -I $REPOPATH/lib/include -I $REPOPATH/lib/src -o $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/mac/x86_64/libtree-sitter.jnilib $ZIGFILES + zig cc -g0 -O2 -shared -target aarch64-macos -std=c11 -I $REPOPATH/lib/include -I $REPOPATH/lib/src -o $TARGETMODULEPATH/src/main/resources/org/springframework/shell/treesitter/libs/mac/arm64/libtree-sitter.jnilib $ZIGFILES +fi diff --git a/settings.gradle b/settings.gradle index 545cdaed1..72d7a7e5c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -48,6 +48,7 @@ include 'spring-shell-standard-commands' include 'spring-shell-table' include 'spring-shell-test' include 'spring-shell-test-autoconfigure' +include 'spring-shell-treesitter' file("${rootDir}/spring-shell-starters").eachDirMatch(~/spring-shell-starter.*/) { include "spring-shell-starters:${it.name}" @@ -57,6 +58,10 @@ file("${rootDir}/spring-shell-samples").eachDirMatch(~/spring-shell-sample.*/) { include "spring-shell-samples:${it.name}" } +file("${rootDir}/spring-shell-treesitter-languages").eachDirMatch(~/spring-shell-treesitter-language.*/) { + include "spring-shell-treesitter-languages:${it.name}" +} + rootProject.children.each { project -> if (project.name == 'spring-shell-starters') { project.children.each { subproject -> @@ -68,6 +73,11 @@ rootProject.children.each { project -> subproject.buildFileName = "${subproject.name}.gradle" } } + else if (project.name == 'spring-shell-treesitter-languages') { + project.children.each { subproject -> + subproject.buildFileName = "${subproject.name}.gradle" + } + } else { project.buildFileName = "${project.name}.gradle" } diff --git a/spring-shell-samples/spring-shell-sample-ffm/sample/code1.java b/spring-shell-samples/spring-shell-sample-ffm/sample/code1.java new file mode 100644 index 000000000..d2887fbdb --- /dev/null +++ b/spring-shell-samples/spring-shell-sample-ffm/sample/code1.java @@ -0,0 +1,7 @@ +package demo; + +class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } +} diff --git a/spring-shell-samples/spring-shell-sample-ffm/sample/code1.json b/spring-shell-samples/spring-shell-sample-ffm/sample/code1.json new file mode 100644 index 000000000..b694f654b --- /dev/null +++ b/spring-shell-samples/spring-shell-sample-ffm/sample/code1.json @@ -0,0 +1,5 @@ +{ + "stringkey": "stringvalue", + "intkey": 1, + "stringarraykey": ["string1", "string2"] +} diff --git a/spring-shell-samples/spring-shell-sample-ffm/sample/code1.yaml b/spring-shell-samples/spring-shell-sample-ffm/sample/code1.yaml new file mode 100644 index 000000000..5e7373ef4 --- /dev/null +++ b/spring-shell-samples/spring-shell-sample-ffm/sample/code1.yaml @@ -0,0 +1,5 @@ +stringkey: stringvalue +intkey: 1 +stringarraykey: + - string1 + - string2 diff --git a/spring-shell-samples/spring-shell-sample-ffm/spring-shell-sample-ffm.gradle b/spring-shell-samples/spring-shell-sample-ffm/spring-shell-sample-ffm.gradle index 25a6f61fa..f245a1285 100644 --- a/spring-shell-samples/spring-shell-sample-ffm/spring-shell-sample-ffm.gradle +++ b/spring-shell-samples/spring-shell-sample-ffm/spring-shell-sample-ffm.gradle @@ -14,6 +14,7 @@ tasks.named("bootJar") { dependencies { management platform(project(":spring-shell-management")) implementation project(':spring-shell-starters:spring-shell-starter-ffm') + implementation project(':spring-shell-starters:spring-shell-starter-treesitter-all') testImplementation project(':spring-shell-starters:spring-shell-starter-test') testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.awaitility:awaitility' diff --git a/spring-shell-samples/spring-shell-sample-ffm/src/main/java/org/springframework/shell/samples/ffm/FfmConfiguration.java b/spring-shell-samples/spring-shell-sample-ffm/src/main/java/org/springframework/shell/samples/ffm/FfmConfiguration.java new file mode 100644 index 000000000..6cc52a717 --- /dev/null +++ b/spring-shell-samples/spring-shell-sample-ffm/src/main/java/org/springframework/shell/samples/ffm/FfmConfiguration.java @@ -0,0 +1,92 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.samples.ffm; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; +import org.springframework.shell.command.annotation.CommandScan; +import org.springframework.shell.style.FigureSettings; +import org.springframework.shell.style.StyleSettings; +import org.springframework.shell.style.Theme; +import org.springframework.shell.style.ThemeSettings; +import org.springframework.shell.treesitter.TreeSitterLanguages; + +@Configuration +@CommandScan +class FfmConfiguration { + + @Bean + public TreeSitterLanguages treeSitterLanguages(ConfigurableListableBeanFactory beanFactory, ResourceLoader resourceLoader) { + return new TreeSitterLanguages(beanFactory, resourceLoader); + } + + @Bean + public Theme customTheme() { + return new Theme() { + @Override + public String getName() { + return "custom"; + } + @Override + public ThemeSettings getSettings() { + return new CustomThemeSettings(); + } + }; + } + + static class CustomThemeSettings extends ThemeSettings { + CustomThemeSettings() { + super(new CustomStyleSettings(), FigureSettings.defaults()); + } + } + + static class CustomStyleSettings extends StyleSettings { + + @Override + public String highlight() { + return "bold,italic,fg:bright-cyan"; + } + + @Override + public String background() { + return "bg:blue"; + } + + @Override + public String dialogBackground() { + return "bg:green"; + } + + @Override + public String buttonBackground() { + return "bg:red"; + } + + @Override + public String menubarBackground() { + return "bg:magenta"; + } + + @Override + public String statusbarBackground() { + return "bg:cyan"; + } + + } + +} diff --git a/spring-shell-samples/spring-shell-sample-ffm/src/main/java/org/springframework/shell/samples/ffm/TreesitterCommand.java b/spring-shell-samples/spring-shell-sample-ffm/src/main/java/org/springframework/shell/samples/ffm/TreesitterCommand.java new file mode 100644 index 000000000..0e855e2b7 --- /dev/null +++ b/spring-shell-samples/spring-shell-sample-ffm/src/main/java/org/springframework/shell/samples/ffm/TreesitterCommand.java @@ -0,0 +1,244 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.samples.ffm; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import org.apache.commons.io.FilenameUtils; +import org.jline.utils.AttributedStringBuilder; +import org.jline.utils.AttributedStyle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.shell.command.annotation.Command; +import org.springframework.shell.command.annotation.Option; +import org.springframework.shell.standard.AbstractShellComponent; +import org.springframework.shell.treesitter.TreeSitterLanguages; +import org.springframework.shell.treesitter.TreeSitterPoint; +import org.springframework.shell.treesitter.TreeSitterQueryMatch; +import org.springframework.util.FileCopyUtils; + +/** + * Main command access point to view showcase catalog. + * + * @author Janne Valkealahti + */ +@Command(command = "treesitter") +public class TreesitterCommand extends AbstractShellComponent { + + private final static Logger log = LoggerFactory.getLogger(TreesitterCommand.class); + + @Autowired + TreeSitterLanguages treeSitterLanguages; + + @Command(command = "info", description = "Info about supported languages") + public String info() { + return treeSitterLanguages.getLanguageProviders().stream().map(l -> l.getClass().toString()) + .collect(Collectors.joining(",")); + } + + @Command(command = "query", description = "Execute default highlight query for given file") + public String query( + @Option(required = true, defaultValue = "Path to a file, extension is the language id") File file + ) throws IOException { + + if (!file.exists()) { + return String.format("File %s doesn't exist", file.getAbsolutePath()); + } + + String language = FilenameUtils.getExtension(file.getName()); + if (!treeSitterLanguages.getSupportedLanguages().contains(language)) { + return String.format("Language with extension %s not supported", language); + } + + byte[] bytes = FileCopyUtils.copyToByteArray(file); + List matches = treeSitterLanguages.languageMatch(language, bytes); + StringBuilder builder = new StringBuilder(); + for (TreeSitterQueryMatch treeSitterQueryMatch : matches) { + treeSitterQueryMatch.getCaptures().forEach(c -> { + TreeSitterPoint startPoint = c.getNode().getStartPoint(); + TreeSitterPoint endPoint = c.getNode().getEndPoint(); + int startByte = c.getNode().getStartByte(); + int endByte = c.getNode().getEndByte(); + byte[] copyOfRange = Arrays.copyOfRange(bytes, startByte, endByte); + + builder.append( + String.format("pattern: %s, capture: %s - [%s], start: (%s,%s), end: (%s,%s), text: `%s`", + treeSitterQueryMatch.getPatternIndex(), treeSitterQueryMatch.getCaptureIndex(), + treeSitterQueryMatch.getNames().stream().collect(Collectors.joining(", ")), + startPoint.row(), startPoint.column(), + endPoint.row(), endPoint.column(), new String(copyOfRange))); + builder.append(System.lineSeparator()); + }); + } + return builder.toString(); + } + + @Command(command = "highlight", description = "Syntax highlight a given file") + public String highlight( + @Option(required = true, defaultValue = "Path to a file, extension is the language id") File file + ) throws IOException { + if (!file.exists()) { + return String.format("File %s doesn't exist", file.getAbsolutePath()); + } + + String language = FilenameUtils.getExtension(file.getName()); + if (!treeSitterLanguages.getSupportedLanguages().contains(language)) { + return String.format("Language with extension %s not supported", language); + } + + byte[] bytes = FileCopyUtils.copyToByteArray(file); + + List matches = treeSitterLanguages.languageMatch(language, bytes); + + List highlights = new ArrayList<>(); + int hIndex = -1; + + for (TreeSitterQueryMatch treeSitterQueryMatch : matches) { + treeSitterQueryMatch.getCaptures().forEach(c -> { + int startByte = c.getNode().getStartByte(); + int endByte = c.getNode().getEndByte(); + if (endByte > hIndex) { + highlights.add(new HighlightData(treeSitterQueryMatch.getNames().getLast(), startByte, endByte)); + } + + }); + } + + StringBuilder buf = new StringBuilder(); + int ti = 0; + + for (HighlightData data : highlights) { + int startByte = data.start(); + int endByte = data.end(); + String hKey = data.key(); + if (startByte >= ti) { + byte[] x1 = new byte[startByte - ti]; + System.arraycopy(bytes, ti, x1, 0, startByte - ti); + buf.append(new String(x1)); + byte[] x2 = new byte[endByte - startByte]; + System.arraycopy(bytes, startByte, x2, 0, endByte - startByte); + + HighlightValue highlightData = findHighlightData(hKey); + + AttributedStringBuilder asb = new AttributedStringBuilder(); + if (highlightData != null) { + AttributedStyle style = new AttributedStyle(); + if (highlightData.color() > -1) { + style = style.foregroundRgb(highlightData.color()); + } + if (highlightData.bold()) { + style = style.bold(); + } + if (highlightData.italic()) { + style = style.italic(); + } + if (highlightData.underline()) { + style = style.underline(); + } + asb.style(style); + } + asb.append(new String(x2)); + buf.append(asb.toAnsi()); + + ti = endByte; + } + } + + if (ti < bytes.length) { + byte[] x = new byte[bytes.length - ti]; + System.arraycopy(bytes, ti, x, 0, bytes.length - ti); + buf.append(new String(x)); + } + + // String out = new String(bytes); + String out = buf.toString(); + return out; + } + + // void ts_parser_delete(TSParser *self); + // void ts_tree_delete(TSTree *self); + // void ts_tree_cursor_delete(TSTreeCursor *self); + // void ts_query_delete(TSQuery *self); + // void ts_query_cursor_delete(TSQueryCursor *self); + // void ts_language_delete(const TSLanguage *self); + // void ts_lookahead_iterator_delete(TSLookaheadIterator *self); + // void ts_wasm_store_delete(TSWasmStore *); + + private record HighlightData(String key, int start, int end) { + } + + private static Map highlightValues = new HashMap<>(); + + private static HighlightValue findHighlightData(String key) { + HighlightValue v = null; + int s = 0; + for (Entry e : highlightValues.entrySet()) { + if (e.getKey().startsWith(key)) { + int size = e.getKey().split("\\.").length; + if (size > s) { + v = e.getValue(); + s = size; + } + } + } + log.debug(String.format("XXX key %s picking %s", key, v)); + return v; + } + + static { + highlightValues.put("attribute", new HighlightValue(0xaf0000, false, true, false)); + highlightValues.put("comment", new HighlightValue(0x8a8a8a, false, true, false)); + highlightValues.put("constant.builtin", new HighlightValue(0x875f00, true, false, false)); + highlightValues.put("constant", new HighlightValue(0x875f00, false, false, false)); + highlightValues.put("constructor", new HighlightValue(0xaf8700, false, false, false)); + highlightValues.put("embedded", new HighlightValue(-1, false, false, false)); + highlightValues.put("function.builtin", new HighlightValue(0x005fd7, true, false, false)); + highlightValues.put("function", new HighlightValue(0x005fd7, false, false, false)); + highlightValues.put("keyword", new HighlightValue(0x5f00d7, false, false, false)); + highlightValues.put("number", new HighlightValue(0x875f00, true, false, false)); + highlightValues.put("module", new HighlightValue(0xaf8700, false, false, false)); + highlightValues.put("property", new HighlightValue(0xaf0000, false, false, false)); + highlightValues.put("operator", new HighlightValue(0x4e4e4e, true, false, false)); + highlightValues.put("punctuation.bracket", new HighlightValue(0x4e4e4e, false, false, false)); + highlightValues.put("punctuation.delimiter", new HighlightValue(0x4e4e4e, false, false, false)); + highlightValues.put("string.special", new HighlightValue(0x008787, false, false, false)); + highlightValues.put("string", new HighlightValue(0x008700, false, false, false)); + highlightValues.put("tag", new HighlightValue(0x000087, false, false, false)); + highlightValues.put("type", new HighlightValue(0x005f5f, false, false, false)); + highlightValues.put("type.builtin", new HighlightValue(0x005f5f, true, false, false)); + highlightValues.put("variable.builtin", new HighlightValue(-1, true, false, false)); + highlightValues.put("variable.parameter", new HighlightValue(-1, false, false, true)); + } + + private record HighlightValue(int color, boolean bold, boolean italic, boolean underline) { + + @Override + public String toString() { + return String.format("HighlightValue [color=%s, bold=%s, italic=%s, underline=%s]", color, bold, italic, underline); + } + + } +} diff --git a/spring-shell-samples/spring-shell-sample-ffm/src/main/resources/application.yml b/spring-shell-samples/spring-shell-sample-ffm/src/main/resources/application.yml index 8b75a2cca..3ff17cb16 100644 --- a/spring-shell-samples/spring-shell-sample-ffm/src/main/resources/application.yml +++ b/spring-shell-samples/spring-shell-sample-ffm/src/main/resources/application.yml @@ -9,10 +9,10 @@ logging: pattern: console: ## log debug from a cli - # file: - # name: shell-ffm.log - # level: - # root: debug - # org: - # springframework: - # shell: debug + file: + name: shell-ffm.log + level: + # root: debug + org: + springframework: + shell: debug diff --git a/spring-shell-starters/spring-shell-starter-treesitter-all/spring-shell-starter-treesitter-all.gradle b/spring-shell-starters/spring-shell-starter-treesitter-all/spring-shell-starter-treesitter-all.gradle new file mode 100644 index 000000000..83b9e8df1 --- /dev/null +++ b/spring-shell-starters/spring-shell-starter-treesitter-all/spring-shell-starter-treesitter-all.gradle @@ -0,0 +1,15 @@ +plugins { + id 'org.springframework.shell.starter' + id 'org.springframework.shell.toolchain' +} + +description = 'Spring Shell Starter Treesitter All' + +dependencies { + management platform(project(":spring-shell-management")) + api(project(':spring-shell-starters:spring-shell-starter')) + api(project(":spring-shell-treesitter")) + file("${rootDir}/spring-shell-treesitter-languages").eachDirMatch(~/spring-shell-treesitter-language.*/) { + api(project(":spring-shell-treesitter-languages:${it.name}")) + } +} diff --git a/spring-shell-treesitter-languages/README.adoc b/spring-shell-treesitter-languages/README.adoc new file mode 100644 index 000000000..f76b6dd1a --- /dev/null +++ b/spring-shell-treesitter-languages/README.adoc @@ -0,0 +1,10 @@ += Spring Shell Treesitter Languages + +Modules in this space depends on `spring-shell-treesitter` and are mostly +generated programmatically based on available `treesitter` languages. + +Not yet full build automation so some things here for reminder: + +Generate java api and compile shared libs. These needs jextract and zig locally. + +scripts/generate-languages.sh -jz diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/spring-shell-treesitter-language-java.gradle b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/spring-shell-treesitter-language-java.gradle new file mode 100644 index 000000000..32c0e4880 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/spring-shell-treesitter-language-java.gradle @@ -0,0 +1,12 @@ +plugins { + id 'org.springframework.shell.module' + id 'org.springframework.shell.toolchain' +} + +description = 'Spring Shell Treesitter Java' + +dependencies { + management platform(project(":spring-shell-management")) + implementation project(':spring-shell-treesitter') + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/java/org/springframework/shell/treesitter/language/java/TreeSitterLanguageJava.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/java/org/springframework/shell/treesitter/language/java/TreeSitterLanguageJava.java new file mode 100644 index 000000000..b4495d586 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/java/org/springframework/shell/treesitter/language/java/TreeSitterLanguageJava.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.language.java; + +import java.lang.foreign.MemorySegment; +import java.util.List; + +import org.springframework.shell.treesitter.AbstractTreeSitterLanguage; +import org.springframework.shell.treesitter.language.java.ts.TreeSitterJava; + +public class TreeSitterLanguageJava extends AbstractTreeSitterLanguage { + + @Override + public boolean supports(String languageName) { + return "java".equals(languageName); + } + + @Override + public List supportedLanguages() { + return List.of("java"); + } + + @Override + public TreeSitterLanguageJava language() { + return this; + } + + @Override + public String highlightQuery() { + return resourceAsString(resourceLoader.getResource("classpath:org/springframework/shell/treesitter/queries/java/highlights.scm")); + } + + @Override + public MemorySegment initInternal() { + MemorySegment java = TreeSitterJava.tree_sitter_java(); + return java; + } + +} diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/java/org/springframework/shell/treesitter/language/java/ts/TreeSitterJava.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/java/org/springframework/shell/treesitter/language/java/ts/TreeSitterJava.java new file mode 100644 index 000000000..251a991de --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/java/org/springframework/shell/treesitter/language/java/ts/TreeSitterJava.java @@ -0,0 +1,128 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.language.java.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +public class TreeSitterJava { + + TreeSitterJava() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args) + .map(Object::toString) + .collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol) + .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream() + .map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? + MemoryLayout.structLayout(alignedMembers) : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup() + .or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + + private static class tree_sitter_java { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitterJava.C_POINTER ); + + public static final MemorySegment ADDR = TreeSitterJava.findOrThrow("tree_sitter_java"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_java() + * } + */ + public static FunctionDescriptor tree_sitter_java$descriptor() { + return tree_sitter_java.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_java() + * } + */ + public static MethodHandle tree_sitter_java$handle() { + return tree_sitter_java.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_java() + * } + */ + public static MemorySegment tree_sitter_java$address() { + return tree_sitter_java.ADDR; + } + + /** + * {@snippet lang=c : + * const TSLanguage *tree_sitter_java() + * } + */ + public static MemorySegment tree_sitter_java() { + var mh$ = tree_sitter_java.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("tree_sitter_java"); + } + return (MemorySegment)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } +} + diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/resources/META-INF/spring/treesitter.factories b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/resources/META-INF/spring/treesitter.factories new file mode 100644 index 000000000..b7d8ab1af --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/resources/META-INF/spring/treesitter.factories @@ -0,0 +1,2 @@ +org.springframework.shell.treesitter.TreeSitterLanguageProvider=\ +org.springframework.shell.treesitter.language.java.TreeSitterLanguageJava diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/resources/org/springframework/shell/treesitter/queries/java/highlights.scm b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/resources/org/springframework/shell/treesitter/queries/java/highlights.scm new file mode 100644 index 000000000..9f5b7d6ad --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/main/resources/org/springframework/shell/treesitter/queries/java/highlights.scm @@ -0,0 +1,146 @@ +; Variables + +(identifier) @variable + +; Methods + +(method_declaration + name: (identifier) @function.method) +(method_invocation + name: (identifier) @function.method) +(super) @function.builtin + +; Annotations + +(annotation + name: (identifier) @attribute) +(marker_annotation + name: (identifier) @attribute) + +"@" @operator + +; Types + +(type_identifier) @type + +(interface_declaration + name: (identifier) @type) +(class_declaration + name: (identifier) @type) +(enum_declaration + name: (identifier) @type) + +((field_access + object: (identifier) @type) + (#match? @type "^[A-Z]")) +((scoped_identifier + scope: (identifier) @type) + (#match? @type "^[A-Z]")) +((method_invocation + object: (identifier) @type) + (#match? @type "^[A-Z]")) +((method_reference + . (identifier) @type) + (#match? @type "^[A-Z]")) + +(constructor_declaration + name: (identifier) @type) + +[ + (boolean_type) + (integral_type) + (floating_point_type) + (floating_point_type) + (void_type) +] @type.builtin + +; Constants + +((identifier) @constant + (#match? @constant "^_*[A-Z][A-Z\\d_]+$")) + +; Builtins + +(this) @variable.builtin + +; Literals + +[ + (hex_integer_literal) + (decimal_integer_literal) + (octal_integer_literal) + (decimal_floating_point_literal) + (hex_floating_point_literal) +] @number + +[ + (character_literal) + (string_literal) +] @string +(escape_sequence) @string.escape + +[ + (true) + (false) + (null_literal) +] @constant.builtin + +[ + (line_comment) + (block_comment) +] @comment + +; Keywords + +[ + "abstract" + "assert" + "break" + "case" + "catch" + "class" + "continue" + "default" + "do" + "else" + "enum" + "exports" + "extends" + "final" + "finally" + "for" + "if" + "implements" + "import" + "instanceof" + "interface" + "module" + "native" + "new" + "non-sealed" + "open" + "opens" + "package" + "private" + "protected" + "provides" + "public" + "requires" + "record" + "return" + "sealed" + "static" + "strictfp" + "switch" + "synchronized" + "throw" + "throws" + "to" + "transient" + "transitive" + "try" + "uses" + "volatile" + "while" + "with" +] @keyword diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/test/java/org/springframework/shell/treesitter/language/java/TreeSitterLanguageJavaTests.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/test/java/org/springframework/shell/treesitter/language/java/TreeSitterLanguageJavaTests.java new file mode 100644 index 000000000..cb77e2799 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/test/java/org/springframework/shell/treesitter/language/java/TreeSitterLanguageJavaTests.java @@ -0,0 +1,38 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.language.java; + +import java.lang.foreign.MemorySegment; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.TreeSitterNativeLoader; +import org.springframework.shell.treesitter.language.java.ts.TreeSitterJava; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TreeSitterLanguageJavaTests { + + @Test + @Tag("treesitter") + void languageLoads() { + TreeSitterNativeLoader.initializeLanguage("java"); + MemorySegment segment = TreeSitterJava.tree_sitter_java(); + assertThat(segment).isNotNull(); + } + +} \ No newline at end of file diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/ts/tree-sitter-java.h b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/ts/tree-sitter-java.h new file mode 100644 index 000000000..fab7c6d94 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-java/src/ts/tree-sitter-java.h @@ -0,0 +1,16 @@ +#ifndef TREE_SITTER_JAVA_H_ +#define TREE_SITTER_JAVA_H_ + +typedef struct TSLanguage TSLanguage; + +#ifdef __cplusplus +extern "C" { +#endif + +const TSLanguage *tree_sitter_java(void); + +#ifdef __cplusplus +} +#endif + +#endif // TREE_SITTER_JAVA_H_ diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/spring-shell-treesitter-language-json.gradle b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/spring-shell-treesitter-language-json.gradle new file mode 100644 index 000000000..6fcd6c1d8 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/spring-shell-treesitter-language-json.gradle @@ -0,0 +1,12 @@ +plugins { + id 'org.springframework.shell.module' + id 'org.springframework.shell.toolchain' +} + +description = 'Spring Shell Treesitter Json' + +dependencies { + management platform(project(":spring-shell-management")) + implementation project(':spring-shell-treesitter') + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/java/org/springframework/shell/treesitter/language/json/TreeSitterLanguageJson.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/java/org/springframework/shell/treesitter/language/json/TreeSitterLanguageJson.java new file mode 100644 index 000000000..3968a1071 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/java/org/springframework/shell/treesitter/language/json/TreeSitterLanguageJson.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.language.json; + +import java.lang.foreign.MemorySegment; +import java.util.List; + +import org.springframework.shell.treesitter.AbstractTreeSitterLanguage; +import org.springframework.shell.treesitter.language.json.ts.TreeSitterJson; + +public class TreeSitterLanguageJson extends AbstractTreeSitterLanguage { + + @Override + public boolean supports(String languageName) { + return "json".equals(languageName); + } + + @Override + public List supportedLanguages() { + return List.of("json"); + } + + @Override + public TreeSitterLanguageJson language() { + return this; + } + + @Override + public String highlightQuery() { + return resourceAsString(resourceLoader.getResource("classpath:org/springframework/shell/treesitter/queries/json/highlights.scm")); + } + + @Override + public MemorySegment initInternal() { + MemorySegment json = TreeSitterJson.tree_sitter_json(); + return json; + } + +} diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/java/org/springframework/shell/treesitter/language/json/ts/TreeSitterJson.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/java/org/springframework/shell/treesitter/language/json/ts/TreeSitterJson.java new file mode 100644 index 000000000..a9747f32f --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/java/org/springframework/shell/treesitter/language/json/ts/TreeSitterJson.java @@ -0,0 +1,128 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.language.json.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +public class TreeSitterJson { + + TreeSitterJson() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args) + .map(Object::toString) + .collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol) + .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream() + .map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? + MemoryLayout.structLayout(alignedMembers) : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup() + .or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + + private static class tree_sitter_json { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitterJson.C_POINTER ); + + public static final MemorySegment ADDR = TreeSitterJson.findOrThrow("tree_sitter_json"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_json() + * } + */ + public static FunctionDescriptor tree_sitter_json$descriptor() { + return tree_sitter_json.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_json() + * } + */ + public static MethodHandle tree_sitter_json$handle() { + return tree_sitter_json.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_json() + * } + */ + public static MemorySegment tree_sitter_json$address() { + return tree_sitter_json.ADDR; + } + + /** + * {@snippet lang=c : + * const TSLanguage *tree_sitter_json() + * } + */ + public static MemorySegment tree_sitter_json() { + var mh$ = tree_sitter_json.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("tree_sitter_json"); + } + return (MemorySegment)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } +} + diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/resources/META-INF/spring/treesitter.factories b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/resources/META-INF/spring/treesitter.factories new file mode 100644 index 000000000..8737129c2 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/resources/META-INF/spring/treesitter.factories @@ -0,0 +1,2 @@ +org.springframework.shell.treesitter.TreeSitterLanguageProvider=\ +org.springframework.shell.treesitter.language.json.TreeSitterLanguageJson diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/resources/org/springframework/shell/treesitter/queries/json/highlights.scm b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/resources/org/springframework/shell/treesitter/queries/json/highlights.scm new file mode 100644 index 000000000..ece8392f0 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/main/resources/org/springframework/shell/treesitter/queries/json/highlights.scm @@ -0,0 +1,16 @@ +(pair + key: (_) @string.special.key) + +(string) @string + +(number) @number + +[ + (null) + (true) + (false) +] @constant.builtin + +(escape_sequence) @escape + +(comment) @comment diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/test/java/org/springframework/shell/treesitter/language/json/TreeSitterLanguageJsonTests.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/test/java/org/springframework/shell/treesitter/language/json/TreeSitterLanguageJsonTests.java new file mode 100644 index 000000000..c9ffa27ca --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/test/java/org/springframework/shell/treesitter/language/json/TreeSitterLanguageJsonTests.java @@ -0,0 +1,38 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.language.json; + +import java.lang.foreign.MemorySegment; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.TreeSitterNativeLoader; +import org.springframework.shell.treesitter.language.json.ts.TreeSitterJson; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TreeSitterLanguageJsonTests { + + @Test + @Tag("treesitter") + void languageLoads() { + TreeSitterNativeLoader.initializeLanguage("json"); + MemorySegment segment = TreeSitterJson.tree_sitter_json(); + assertThat(segment).isNotNull(); + } + +} \ No newline at end of file diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/ts/tree-sitter-json.h b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/ts/tree-sitter-json.h new file mode 100644 index 000000000..70965f451 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-json/src/ts/tree-sitter-json.h @@ -0,0 +1,16 @@ +#ifndef TREE_SITTER_JSON_H_ +#define TREE_SITTER_JSON_H_ + +typedef struct TSLanguage TSLanguage; + +#ifdef __cplusplus +extern "C" { +#endif + +const TSLanguage *tree_sitter_json(void); + +#ifdef __cplusplus +} +#endif + +#endif // TREE_SITTER_JSON_H_ diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/spring-shell-treesitter-language-yaml.gradle b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/spring-shell-treesitter-language-yaml.gradle new file mode 100644 index 000000000..c256b5a40 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/spring-shell-treesitter-language-yaml.gradle @@ -0,0 +1,12 @@ +plugins { + id 'org.springframework.shell.module' + id 'org.springframework.shell.toolchain' +} + +description = 'Spring Shell Treesitter Yaml' + +dependencies { + management platform(project(":spring-shell-management")) + implementation project(':spring-shell-treesitter') + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/java/org/springframework/shell/treesitter/language/yaml/TreeSitterLanguageYaml.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/java/org/springframework/shell/treesitter/language/yaml/TreeSitterLanguageYaml.java new file mode 100644 index 000000000..5837af541 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/java/org/springframework/shell/treesitter/language/yaml/TreeSitterLanguageYaml.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.language.yaml; + +import java.lang.foreign.MemorySegment; +import java.util.List; + +import org.springframework.shell.treesitter.AbstractTreeSitterLanguage; +import org.springframework.shell.treesitter.language.yaml.ts.TreeSitterYaml; + +public class TreeSitterLanguageYaml extends AbstractTreeSitterLanguage { + + @Override + public boolean supports(String languageName) { + return "yaml".equals(languageName); + } + + @Override + public List supportedLanguages() { + return List.of("yaml"); + } + + @Override + public TreeSitterLanguageYaml language() { + return this; + } + + @Override + public String highlightQuery() { + return resourceAsString(resourceLoader.getResource("classpath:org/springframework/shell/treesitter/queries/yaml/highlights.scm")); + } + + @Override + public MemorySegment initInternal() { + MemorySegment yaml = TreeSitterYaml.tree_sitter_yaml(); + return yaml; + } + +} diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/java/org/springframework/shell/treesitter/language/yaml/ts/TreeSitterYaml.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/java/org/springframework/shell/treesitter/language/yaml/ts/TreeSitterYaml.java new file mode 100644 index 000000000..d71186f1f --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/java/org/springframework/shell/treesitter/language/yaml/ts/TreeSitterYaml.java @@ -0,0 +1,128 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.language.yaml.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +public class TreeSitterYaml { + + TreeSitterYaml() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args) + .map(Object::toString) + .collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol) + .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream() + .map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? + MemoryLayout.structLayout(alignedMembers) : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup() + .or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + + private static class tree_sitter_yaml { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitterYaml.C_POINTER ); + + public static final MemorySegment ADDR = TreeSitterYaml.findOrThrow("tree_sitter_yaml"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_yaml() + * } + */ + public static FunctionDescriptor tree_sitter_yaml$descriptor() { + return tree_sitter_yaml.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_yaml() + * } + */ + public static MethodHandle tree_sitter_yaml$handle() { + return tree_sitter_yaml.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSLanguage *tree_sitter_yaml() + * } + */ + public static MemorySegment tree_sitter_yaml$address() { + return tree_sitter_yaml.ADDR; + } + + /** + * {@snippet lang=c : + * const TSLanguage *tree_sitter_yaml() + * } + */ + public static MemorySegment tree_sitter_yaml() { + var mh$ = tree_sitter_yaml.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("tree_sitter_yaml"); + } + return (MemorySegment)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } +} + diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/resources/META-INF/spring/treesitter.factories b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/resources/META-INF/spring/treesitter.factories new file mode 100644 index 000000000..33aea81d5 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/resources/META-INF/spring/treesitter.factories @@ -0,0 +1,2 @@ +org.springframework.shell.treesitter.TreeSitterLanguageProvider=\ +org.springframework.shell.treesitter.language.yaml.TreeSitterLanguageYaml diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/resources/org/springframework/shell/treesitter/queries/yaml/highlights.scm b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/resources/org/springframework/shell/treesitter/queries/yaml/highlights.scm new file mode 100644 index 000000000..cb9dcc622 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/main/resources/org/springframework/shell/treesitter/queries/yaml/highlights.scm @@ -0,0 +1,79 @@ +(boolean_scalar) @boolean + +(null_scalar) @constant.builtin + +[ + (double_quote_scalar) + (single_quote_scalar) + (block_scalar) + (string_scalar) +] @string + +[ + (integer_scalar) + (float_scalar) +] @number + +(comment) @comment + +[ + (anchor_name) + (alias_name) +] @label + +(tag) @type + +[ + (yaml_directive) + (tag_directive) + (reserved_directive) +] @attribute + +(block_mapping_pair + key: (flow_node + [ + (double_quote_scalar) + (single_quote_scalar) + ] @property)) + +(block_mapping_pair + key: (flow_node + (plain_scalar + (string_scalar) @property))) + +(flow_mapping + (_ + key: (flow_node + [ + (double_quote_scalar) + (single_quote_scalar) + ] @property))) + +(flow_mapping + (_ + key: (flow_node + (plain_scalar + (string_scalar) @property)))) + +[ + "," + "-" + ":" + ">" + "?" + "|" +] @punctuation.delimiter + +[ + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "*" + "&" + "---" + "..." +] @punctuation.special diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/test/java/org/springframework/shell/treesitter/language/yaml/TreeSitterLanguageYamlTests.java b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/test/java/org/springframework/shell/treesitter/language/yaml/TreeSitterLanguageYamlTests.java new file mode 100644 index 000000000..3874b1990 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/test/java/org/springframework/shell/treesitter/language/yaml/TreeSitterLanguageYamlTests.java @@ -0,0 +1,38 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.language.yaml; + +import java.lang.foreign.MemorySegment; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.TreeSitterNativeLoader; +import org.springframework.shell.treesitter.language.yaml.ts.TreeSitterYaml; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TreeSitterLanguageYamlTests { + + @Test + @Tag("treesitter") + void languageLoads() { + TreeSitterNativeLoader.initializeLanguage("yaml"); + MemorySegment segment = TreeSitterYaml.tree_sitter_yaml(); + assertThat(segment).isNotNull(); + } + +} \ No newline at end of file diff --git a/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/ts/tree-sitter-yaml.h b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/ts/tree-sitter-yaml.h new file mode 100644 index 000000000..ce248bb32 --- /dev/null +++ b/spring-shell-treesitter-languages/spring-shell-treesitter-language-yaml/src/ts/tree-sitter-yaml.h @@ -0,0 +1,16 @@ +#ifndef TREE_SITTER_YAML_H_ +#define TREE_SITTER_YAML_H_ + +typedef struct TSLanguage TSLanguage; + +#ifdef __cplusplus +extern "C" { +#endif + +const TSLanguage *tree_sitter_yaml(void); + +#ifdef __cplusplus +} +#endif + +#endif // TREE_SITTER_YAML_H_ diff --git a/spring-shell-treesitter/README.adoc b/spring-shell-treesitter/README.adoc new file mode 100644 index 000000000..ac1b9e124 --- /dev/null +++ b/spring-shell-treesitter/README.adoc @@ -0,0 +1,18 @@ += Spring Shell Treesitter + +Tree-sitter is a native parsing library used by neovim and github to parse various +languages providing services like syntax highlighting. + +Spring Shell Treesitter modules contains a compiled native libraries for linux, +macos and windows to be used via JDK's Foreign Function and Memory API and thus +needs minimum of JDK version 22. + +`spring-shell-treesitter` is our opinionated `tree-sitter` bindings and all +other `spring-shell-treesitter-language-` modules provides support for a +particular language. + +Not yet full build automation so some things here for reminder: + +Generate java api and compile shared libs. These needs jextract and zig locally. + +scripts/generate-ts.sh -jz diff --git a/spring-shell-treesitter/spring-shell-treesitter.gradle b/spring-shell-treesitter/spring-shell-treesitter.gradle new file mode 100644 index 000000000..45bad5094 --- /dev/null +++ b/spring-shell-treesitter/spring-shell-treesitter.gradle @@ -0,0 +1,13 @@ +plugins { + id 'org.springframework.shell.module' + id 'org.springframework.shell.toolchain' +} + +description = 'Spring Shell Treesitter' + +dependencies { + management platform(project(":spring-shell-management")) + api('org.springframework:spring-context') + implementation project(':spring-shell-core') + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/AbstractTreeSitterLanguage.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/AbstractTreeSitterLanguage.java new file mode 100644 index 000000000..114300356 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/AbstractTreeSitterLanguage.java @@ -0,0 +1,68 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UncheckedIOException; +import java.lang.foreign.MemorySegment; +import java.nio.charset.StandardCharsets; + +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.FileCopyUtils; + +/** + * Base class for {@link TreeSitterLanguage} and + * {@link TreeSitterLanguageProvider} typically used in auto-generated classes + * supported by {@code treesitter}. + * + * @author Janne Valkealahti + */ +public abstract class AbstractTreeSitterLanguage + implements TreeSitterLanguage, TreeSitterLanguageProvider, ResourceLoaderAware { + + private MemorySegment segment; + protected ResourceLoader resourceLoader; + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + @Override + public final MemorySegment init() { + synchronized(this) { + if (segment == null) { + segment = initInternal(); + } + } + return segment; + } + + protected abstract MemorySegment initInternal(); + + protected static String resourceAsString(Resource resource) { + try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) { + return FileCopyUtils.copyToString(reader); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguage.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguage.java new file mode 100644 index 000000000..ed5382a32 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguage.java @@ -0,0 +1,43 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.lang.foreign.MemorySegment; + +/** + * Low level {@code treesitter} interface initialising its language and having + * info about query. + * + * @author Janne Valkealahti + */ +public interface TreeSitterLanguage { + + /** + * Initialise a {@code treesitter} language returning its {@link MemorySegment}. + * Memory is expected to get freed by {@code treesitter parser}. + * + * @return a memory segment for initialised language + */ + MemorySegment init(); + + /** + * Get a {@code treesitter} {@code highlight query}. + * + * @return treesitter highlight query + */ + String highlightQuery(); + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguageProvider.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguageProvider.java new file mode 100644 index 000000000..eb1fbbce3 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguageProvider.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.util.List; + +/** + * Interface providing {@link AbstractTreeSitterLanguage} and what languages it + * supports. These are separated so that we don't need to initialise actual + * backing {@code tree-sitter} libraries order to know what languages it + * supports. + * + * @author Janne Valkealahti + */ +public interface TreeSitterLanguageProvider { + + /** + * Checks if this provider supports a {@code language}. + * + * @param languageName the language name + * @return {@code true} if language is supported + */ + boolean supports(String languageName); + + /** + * Gets a list of supported languges. + * + * @return a list of supported languages + */ + List supportedLanguages(); + + /** + * Get a {@link TreeSitterLanguage} this provider handles. + * + * @return a treesitter language + */ + TreeSitterLanguage language(); + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguages.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguages.java new file mode 100644 index 000000000..c77190caf --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterLanguages.java @@ -0,0 +1,83 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.util.List; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.ResourceLoader; + +/** + * + * @author Janne Valkealahti + */ +public class TreeSitterLanguages { + + private TreeSitterServices services; + private ResourceLoader resourceLoader; + + public TreeSitterLanguages(ConfigurableListableBeanFactory beanFactory, ResourceLoader resourceLoader) { + this(TreeSitterServices.factoriesAndBeans(beanFactory)); + this.resourceLoader = resourceLoader; + } + + TreeSitterLanguages(TreeSitterServices.Loader loader) { + services = loader.load(TreeSitterLanguageProvider.class); + } + + public TreeSitterLanguageProvider getLanguageProvider(String language) { + TreeSitterLanguageProvider provider = services.asList().stream() + .filter(l -> l.supports(language)).findFirst() + .orElseThrow(() -> new RuntimeException(String.format("Language %s not supported", language))); + if (provider instanceof ResourceLoaderAware rla) { + rla.setResourceLoader(resourceLoader); + } + return provider; + } + + public List getLanguageProviders() { + return services.asList(); + } + + public List getSupportedLanguages() { + return getLanguageProviders().stream() + .flatMap(provider -> provider.supportedLanguages().stream()) + .toList(); + } + + public List languageMatch(String languageId, byte[] bytes) { + TreeSitterNativeLoader.initialize(); + TreeSitterNativeLoader.initializeLanguage(languageId); + + TreeSitterLanguageProvider provider = getLanguageProvider(languageId); + TreeSitterLanguage language = provider.language(); + + TreeSitterTree tree = null; + try (TreeSitterParser parser = new TreeSitterParser(language)) { + tree = parser.parse(new String(bytes)); + } + + List matches = null; + try (TreeSitterQuery query = new TreeSitterQuery(language, language.highlightQuery());) { + matches = query.findMatches(tree.getRootNode()); + } + + return matches; + } + + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterNativeLoader.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterNativeLoader.java new file mode 100644 index 000000000..442363f3a --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterNativeLoader.java @@ -0,0 +1,415 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Random; + +import org.jline.nativ.OSInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.util.StringUtils; + +/** + * Handles loading of a {@code treesitter} libraries including both main library + * and a related grammar libraries. + * + * @author Janne Valkealahti + */ +public class TreeSitterNativeLoader { + + private static final Logger log = LoggerFactory.getLogger(TreeSitterNativeLoader.class); + private static boolean mainLibLoaded = false; + private static Map languageLibLoaded = new HashMap<>(); + private static String nativeLibraryPath; + private static String nativeLibrarySourceUrl; + + public static synchronized boolean initialize() { + // only cleanup before the first extract + if (!mainLibLoaded) { + Thread cleanup = new Thread(TreeSitterNativeLoader::cleanup, "cleanup"); + cleanup.setPriority(Thread.MIN_PRIORITY); + cleanup.setDaemon(true); + cleanup.start(); + } + try { + loadTreeSitterNativeLibrary(null); + } catch (Exception e) { + throw new RuntimeException("Unable to load treesitter native library: " + e.getMessage(), e); + } + return mainLibLoaded; + // return true; + } + + public static synchronized boolean initializeLanguage(String language) { + // only cleanup before the first extract + if (!languageLibLoaded.computeIfAbsent(language, l -> false)) { + Thread cleanup = new Thread(TreeSitterNativeLoader::cleanup, "cleanup"); + cleanup.setPriority(Thread.MIN_PRIORITY); + cleanup.setDaemon(true); + cleanup.start(); + } + try { + loadTreeSitterNativeLibrary(language); + } catch (Exception e) { + throw new RuntimeException("Unable to load treesitter native library: " + e.getMessage(), e); + } + return languageLibLoaded.computeIfAbsent(language, l -> false); + } + + // public static String getNativeLibraryPath() { + // return nativeLibraryPath; + // } + + // public static String getNativeLibrarySourceUrl() { + // return nativeLibrarySourceUrl; + // } + + private static File getTempDir() { + return new File(System.getProperty("spring-shell.tmpdir", System.getProperty("java.io.tmpdir"))); + } + + /** + * Deleted old native libraries e.g. on Windows the DLL file is not removed + * on VM-Exit (bug #80) + */ + static void cleanup() { + String tempFolder = getTempDir().getAbsolutePath(); + File dir = new File(tempFolder); + + File[] nativeLibFiles = dir.listFiles(new FilenameFilter() { + private final String searchPattern = "treesitter-" + getVersion(); + + public boolean accept(File dir, String name) { + return name.startsWith(searchPattern) && !name.endsWith(".lck"); + } + }); + if (nativeLibFiles != null) { + for (File nativeLibFile : nativeLibFiles) { + File lckFile = new File(nativeLibFile.getAbsolutePath() + ".lck"); + if (!lckFile.exists()) { + try { + nativeLibFile.delete(); + } catch (SecurityException e) { + log.info("Failed to delete old native lib {}", e.getMessage(), e); + } + } + } + } + } + + private static int readNBytes(InputStream in, byte[] b) throws IOException { + int n = 0; + int len = b.length; + while (n < len) { + int count = in.read(b, n, len - n); + if (count <= 0) break; + n += count; + } + return n; + } + + private static String contentsEquals(InputStream in1, InputStream in2) throws IOException { + byte[] buffer1 = new byte[8192]; + byte[] buffer2 = new byte[8192]; + int numRead1; + int numRead2; + while (true) { + numRead1 = readNBytes(in1, buffer1); + numRead2 = readNBytes(in2, buffer2); + if (numRead1 > 0) { + if (numRead2 <= 0) { + return "EOF on second stream but not first"; + } + if (numRead2 != numRead1) { + return "Read size different (" + numRead1 + " vs " + numRead2 + ")"; + } + // Otherwise same number of bytes read + if (!Arrays.equals(buffer1, buffer2)) { + return "Content differs"; + } + // Otherwise same bytes read, so continue ... + } else { + // Nothing more in stream 1 ... + if (numRead2 > 0) { + return "EOF on first stream but not second"; + } else { + return null; + } + } + } + } + + /** + * Extracts and loads the specified library file to the target folder + * + * @param libFolderForCurrentOS Library path. + * @param libraryFileName Library name. + * @param targetFolder Target folder. + * @return + */ + private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName, + String targetFolder) { + String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName; + // Include architecture name in temporary filename in order to avoid conflicts + // when multiple JVMs with different architectures running at the same time + String uuid = randomUUID(); + String extractedLibFileName = String.format("treesitter-%s-%s-%s", getVersion(), uuid, libraryFileName); + String extractedLckFileName = extractedLibFileName + ".lck"; + + File extractedLibFile = new File(targetFolder, extractedLibFileName); + File extractedLckFile = new File(targetFolder, extractedLckFileName); + + try { + // Extract a native library file into the target directory + try (InputStream in = TreeSitterNativeLoader.class.getResourceAsStream(nativeLibraryFilePath)) { + if (!extractedLckFile.exists()) { + new FileOutputStream(extractedLckFile).close(); + } + try (OutputStream out = new FileOutputStream(extractedLibFile)) { + copy(in, out); + } + } finally { + // Delete the extracted lib file on JVM exit. + extractedLibFile.deleteOnExit(); + extractedLckFile.deleteOnExit(); + } + + // Set executable (x) flag to enable Java to load the native library + extractedLibFile.setReadable(true); + extractedLibFile.setWritable(true); + extractedLibFile.setExecutable(true); + + // Check whether the contents are properly copied from the resource folder + try (InputStream nativeIn = TreeSitterNativeLoader.class.getResourceAsStream(nativeLibraryFilePath)) { + try (InputStream extractedLibIn = new FileInputStream(extractedLibFile)) { + String eq = contentsEquals(nativeIn, extractedLibIn); + if (eq != null) { + throw new RuntimeException(String.format( + "Failed to write a native library file at %s because %s", extractedLibFile, eq)); + } + } + } + + // Load library + if (loadNativeLibrary(extractedLibFile)) { + nativeLibrarySourceUrl = TreeSitterNativeLoader.class + .getResource(nativeLibraryFilePath) + .toExternalForm(); + return true; + } + } catch (IOException e) { + // log(Level.WARNING, "Unable to load JLine's native library", e); + } + return false; + } + + private static String randomUUID() { + return Long.toHexString(new Random().nextLong()); + } + + private static void copy(InputStream in, OutputStream out) throws IOException { + byte[] buf = new byte[8192]; + int n; + while ((n = in.read(buf)) > 0) { + out.write(buf, 0, n); + } + } + + /** + * Loads native library using the given path and name of the library. + * + * @param libPath Path of the native library. + * @return True for successfully loading; false otherwise. + */ + private static boolean loadNativeLibrary(File libPath) { + if (libPath.exists()) { + + try { + String path = libPath.getAbsolutePath(); + System.load(path); + nativeLibraryPath = path; + return true; + } catch (UnsatisfiedLinkError e) { + log.warn("Failed to load native library:" + libPath.getName() + ". osinfo: " + + OSInfo.getNativeLibFolderPathForCurrentOS(), e); + return false; + } + + } else { + return false; + } + } + + private static void loadTreeSitterNativeLibrary(String language) throws Exception { + if (StringUtils.hasText(language)) { + if (languageLibLoaded.computeIfAbsent(language, l -> false)) { + return; + } + } + else { + if (mainLibLoaded) { + return; + } + } + + List triedPaths = new ArrayList(); + + String jlineNativeLibraryPath = StringUtils.hasText(language) + ? System.getProperty("library.treesitter." + language + ".path") + : System.getProperty("library.treesitter.path"); + String jlineNativeLibraryName = StringUtils.hasText(language) + ? System.getProperty("library.treesitter." + language + ".name") + : System.getProperty("library.treesitter.name"); + if (jlineNativeLibraryName == null) { + jlineNativeLibraryName = System.mapLibraryName(StringUtils.hasText(language) ? "tree-sitter-" + language : "tree-sitter"); + assert jlineNativeLibraryName != null; + if (jlineNativeLibraryName.endsWith(".dylib")) { + jlineNativeLibraryName = jlineNativeLibraryName.replace(".dylib", ".jnilib"); + } + } + + if (jlineNativeLibraryPath != null) { + String withOs = jlineNativeLibraryPath + "/" + OSInfo.getNativeLibFolderPathForCurrentOS(); + if (loadNativeLibrary(new File(withOs, jlineNativeLibraryName))) { + if (StringUtils.hasText(language)) { + languageLibLoaded.put(language, true); + } + else { + mainLibLoaded = true; + } + return; + } else { + triedPaths.add(withOs); + } + + if (loadNativeLibrary(new File(jlineNativeLibraryPath, jlineNativeLibraryName))) { + if (StringUtils.hasText(language)) { + languageLibLoaded.put(language, true); + } + else { + mainLibLoaded = true; + } + return; + } else { + triedPaths.add(jlineNativeLibraryPath); + } + } + + // Load the os-dependent library from the jar file + String packagePath = TreeSitterNativeLoader.class.getPackage().getName().replace('.', '/') + "/libs"; + jlineNativeLibraryPath = String.format("/%s/%s", packagePath, OSInfo.getNativeLibFolderPathForCurrentOS().toLowerCase()); + boolean hasNativeLib = hasResource(jlineNativeLibraryPath + "/" + jlineNativeLibraryName); + + if (hasNativeLib) { + // temporary library folder + String tempFolder = getTempDir().getAbsolutePath(); + // Try extracting the library from jar + if (extractAndLoadLibraryFile(jlineNativeLibraryPath, jlineNativeLibraryName, tempFolder)) { + if (StringUtils.hasText(language)) { + languageLibLoaded.put(language, true); + } + else { + mainLibLoaded = true; + } + return; + } else { + triedPaths.add(jlineNativeLibraryPath); + } + } + + // As a last resort try from java.library.path + String javaLibraryPath = System.getProperty("java.library.path", ""); + for (String ldPath : javaLibraryPath.split(File.pathSeparator)) { + if (ldPath.isEmpty()) { + continue; + } + if (loadNativeLibrary(new File(ldPath, jlineNativeLibraryName))) { + if (StringUtils.hasText(language)) { + languageLibLoaded.put(language, true); + } + else { + mainLibLoaded = true; + } + return; + } else { + triedPaths.add(ldPath); + } + } + + throw new Exception(String.format( + "No native library found for os.name=%s, os.arch=%s, paths=[%s]", + OSInfo.getOSName(), OSInfo.getArchName(), join(triedPaths, File.pathSeparator))); + } + + private static boolean hasResource(String path) { + return TreeSitterNativeLoader.class.getResource(path) != null; + } + + public static int getMajorVersion() { + String[] c = getVersion().split("\\."); + return (c.length > 0) ? Integer.parseInt(c[0]) : 1; + } + + public static int getMinorVersion() { + String[] c = getVersion().split("\\."); + return (c.length > 1) ? Integer.parseInt(c[1]) : 0; + } + + public static String getVersion() { + URL versionFile = TreeSitterNativeLoader.class.getResource("/META-INF/maven/org.jline/jline-native/pom.properties"); + + String version = "unknown"; + try { + if (versionFile != null) { + Properties versionData = new Properties(); + versionData.load(versionFile.openStream()); + version = versionData.getProperty("version", version); + version = version.trim().replaceAll("[^0-9.]", ""); + } + } catch (IOException e) { + // log(Level.WARNING, "Unable to load jline-native version", e); + } + return version; + } + + private static String join(List list, String separator) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String item : list) { + if (first) first = false; + else sb.append(separator); + + sb.append(item); + } + return sb.toString(); + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterNode.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterNode.java new file mode 100644 index 000000000..49cfa5b1e --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterNode.java @@ -0,0 +1,83 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; + +import org.springframework.shell.treesitter.ts.TSPoint; +import org.springframework.shell.treesitter.ts.TreeSitter; + +/** + * + * @author Janne Valkealahti + */ +public final class TreeSitterNode { + + private final MemorySegment node; + private final TreeSitterPoint startPoint; + private final TreeSitterPoint endPoint; + private final int startByte; + private final int endByte; + private TreeSitterTree tree; + + private TreeSitterNode(MemorySegment node, TreeSitterTree tree, TreeSitterPoint startPoint, TreeSitterPoint endPoint, + int startByte, int endByte) { + this.node = node; + this.tree = tree; + this.startPoint = startPoint; + this.endPoint = endPoint; + this.startByte = startByte; + this.endByte = endByte; + } + + public TreeSitterTree getTree() { + return tree; + } + + protected static TreeSitterNode of(MemorySegment node, TreeSitterTree tree) { + try (Arena arena = Arena.ofConfined()) { + MemorySegment nodeStartPoint = TreeSitter.ts_node_start_point(arena, node); + MemorySegment nodeEndPoint = TreeSitter.ts_node_end_point(arena, node); + TreeSitterPoint startPoint = new TreeSitterPoint(TSPoint.row(nodeStartPoint), TSPoint.column(nodeStartPoint)); + TreeSitterPoint endPoint = new TreeSitterPoint(TSPoint.row(nodeEndPoint), TSPoint.column(nodeEndPoint)); + int startByte = TreeSitter.ts_node_start_byte(node); + int endByte = TreeSitter.ts_node_end_byte(node); + return new TreeSitterNode(node, tree, startPoint, endPoint, startByte, endByte); + } + } + + public TreeSitterPoint getStartPoint() { + return startPoint; + } + + public TreeSitterPoint getEndPoint() { + return endPoint; + } + + public int getStartByte() { + return startByte; + } + + public int getEndByte() { + return endByte; + } + + protected MemorySegment getNode() { + return node; + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterParser.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterParser.java new file mode 100644 index 000000000..304fcaaa7 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterParser.java @@ -0,0 +1,59 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + +import org.springframework.shell.treesitter.ts.TreeSitter; +import org.springframework.util.Assert; + +/** + * + * @author Janne Valkealahti + */ +public class TreeSitterParser implements AutoCloseable { + + private MemorySegment parser; + private final Arena arena; + + public TreeSitterParser(TreeSitterLanguage language) { + Assert.notNull(language, "language must be"); + arena = Arena.ofShared(); + parser = TreeSitter.ts_parser_new().reinterpret(arena, TreeSitter::ts_parser_delete); + // TODO: should handle boolean returned from setting language + TreeSitter.ts_parser_set_language(parser, language.init()); + } + + @Override + public void close() { + arena.close(); + } + + public TreeSitterTree parse(String code) { + return parse(code.getBytes()); + } + + public TreeSitterTree parse(byte[] code) { + try (Arena a = Arena.ofConfined()) { + MemorySegment sourceCode = a.allocateFrom(ValueLayout.JAVA_BYTE, code); + int length = (int) sourceCode.byteSize() - 1; + MemorySegment tree = TreeSitter.ts_parser_parse_string(parser, MemorySegment.NULL, sourceCode, length); + return new TreeSitterTree(tree, code); + } + } +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterPoint.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterPoint.java new file mode 100644 index 000000000..a07aa606d --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterPoint.java @@ -0,0 +1,24 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +/** + * + * @author Janne Valkealahti + */ +public record TreeSitterPoint(int row, int column) { + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQuery.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQuery.java new file mode 100644 index 000000000..e31e519dd --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQuery.java @@ -0,0 +1,207 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; +import java.lang.foreign.ValueLayout.OfInt; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.shell.treesitter.predicate.MatchTreeSitterQueryPredicate; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateArg; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateContext; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateDefinition; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateType; +import org.springframework.shell.treesitter.ts.TSNode; +import org.springframework.shell.treesitter.ts.TSQueryCapture; +import org.springframework.shell.treesitter.ts.TSQueryMatch; +import org.springframework.shell.treesitter.ts.TSQueryPredicateStep; +import org.springframework.shell.treesitter.ts.TreeSitter; +import org.springframework.util.Assert; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +/** + * {@code treesitter} query implementation. + * + * @author Janne Valkealahti + */ +public class TreeSitterQuery implements AutoCloseable { + + private final static Logger log = LoggerFactory.getLogger(TreeSitterQuery.class); + private TreeSitterLanguage language; + private String source; + private final Arena arena; + + public TreeSitterQuery(TreeSitterLanguage language, String source) { + Assert.notNull(language, "language must be"); + Assert.notNull(source, "source must be"); + arena = Arena.ofShared(); + this.language = language; + this.source = source; + } + + @Override + public void close() { + arena.close(); + } + + public List findMatches(TreeSitterNode node) { + MemorySegment cursor = TreeSitter.ts_query_cursor_new().reinterpret(arena, TreeSitter::ts_query_cursor_delete); + MemorySegment languageSegment = language.init(); + MemorySegment sourceSegment = arena.allocateFrom(source); + int sourceLen = source.length(); + MemorySegment error_offset = arena.allocateFrom(OfInt.JAVA_INT, 0); + MemorySegment error_type = arena.allocateFrom(OfInt.JAVA_INT, 0); + MemorySegment querySegment = TreeSitter + .ts_query_new(languageSegment, sourceSegment, sourceLen, error_offset, error_type) + .reinterpret(arena, TreeSitter::ts_query_delete); + TreeSitter.ts_query_cursor_exec(cursor, querySegment, node.getNode()); + + MemorySegment queryMatch = TSQueryMatch.allocate(arena); + + List queryCaptureNames = getQueryCaptureNames(querySegment); + List queryStringValues = getQueryStringValues(querySegment); + MultiValueMap queryPredicates = getQueryPredicates(querySegment, + queryStringValues, queryCaptureNames); + log.info("XXX queryPredicates={}", queryPredicates); + + List matches = new ArrayList<>(); + + while (TreeSitter.ts_query_cursor_next_match(cursor, queryMatch)) { + short patternIndex = TSQueryMatch.pattern_index(queryMatch); + short count = TSQueryMatch.capture_count(queryMatch); + int id = TSQueryMatch.id(queryMatch); + + + MemorySegment captures = TSQueryMatch.captures(queryMatch); + + List queryCaptures = new ArrayList<>(); + + List names = new ArrayList<>(); + for (short i = 0; i < count; ++i) { + MemorySegment capture = TSQueryCapture.asSlice(captures, i); + String name = queryCaptureNames.get(TSQueryCapture.index(capture)); + MemorySegment captureNode = TSNode.allocate(arena).copyFrom(TSQueryCapture.node(capture)); + TreeSitterNode treeSitterNode = TreeSitterNode.of(captureNode, node.getTree()); + TreeSitterQueryCapture treeSitterQueryCapture = new TreeSitterQueryCapture(treeSitterNode, i, name); + queryCaptures.add(treeSitterQueryCapture); + names.add(name); + } + + int index = TSQueryCapture.index(captures); + TreeSitterQueryMatch treeSitterQueryMatch = new TreeSitterQueryMatch(id, patternIndex, index, queryCaptureNames.size(), + queryCaptures, names); + List pList = queryPredicates.get(treeSitterQueryMatch.getPatternIndex()); + boolean add = true; + if (pList != null) { + TreeSitterQueryPredicateContext context = new TreeSitterQueryPredicateContext(treeSitterQueryMatch); + add = pList.stream().allMatch(p -> p.test(context)); + } + + if (add) { + matches.add(treeSitterQueryMatch); + } + } + + return matches; + } + + private List getQueryCaptureNames(MemorySegment querySegment) { + int captureCount = TreeSitter.ts_query_capture_count(querySegment); + List captureNames = new ArrayList<>(captureCount); + try (var alloc = Arena.ofConfined()) { + for (int i = 0; i < captureCount; i++) { + MemorySegment length = arena.allocate(ValueLayout.JAVA_INT); + MemorySegment name = TreeSitter.ts_query_capture_name_for_id(querySegment, i, length); + captureNames.add(name.getString(0)); + } + } + return captureNames; + } + + private List getQueryStringValues(MemorySegment querySegment) { + int stringCount = TreeSitter.ts_query_string_count(querySegment); + List stringValues = new ArrayList<>(stringCount); + try (var alloc = Arena.ofConfined()) { + for (int i = 0; i < stringCount; ++i) { + MemorySegment length = alloc.allocate(ValueLayout.JAVA_INT); + MemorySegment name = TreeSitter.ts_query_string_value_for_id(querySegment, i, length); + stringValues.add(name.getString(0)); + } + } + return stringValues; + } + + private MultiValueMap getQueryPredicates(MemorySegment querySegment, List stringValues, List captureNames) { + MultiValueMap predicates = new LinkedMultiValueMap<>(); + try (Arena alloc = Arena.ofConfined()) { + int patternCount = TreeSitter.ts_query_pattern_count(querySegment); + for (int patternIndex = 0; patternIndex < patternCount; patternIndex++) { + MemorySegment count = alloc.allocate(OfInt.JAVA_INT); + MemorySegment tokens = TreeSitter.ts_query_predicates_for_pattern(querySegment, patternIndex, count); + int steps = count.get(OfInt.JAVA_INT, 0); + log.info("XXX pattern predicate - patternIndex={} steps={}", patternIndex, steps); + + List defs = new ArrayList<>(); + List args = null; + String predicateValue = null; + for (long stepIndex = 0; stepIndex < steps; ++stepIndex) { + if (args == null) { + args = new ArrayList<>(); + } + MemorySegment t = TSQueryPredicateStep.asSlice(tokens, stepIndex); + int type = TSQueryPredicateStep.type(t); + if (type == TreeSitter.TSQueryPredicateStepTypeDone()) { + log.info("XXX pattern steps - patternIndex={} type={} done", patternIndex, type); + defs.add(new TreeSitterQueryPredicateDefinition(predicateValue, args)); + if (MatchTreeSitterQueryPredicate.PREDICATE.equals(predicateValue)) { + log.info("XXX should add {}", predicateValue); + TreeSitterQueryPredicate p = MatchTreeSitterQueryPredicate.of(args); + predicates.add(patternIndex, p); + } + args = null; + predicateValue = null; + continue; + } + else if (type == TreeSitter.TSQueryPredicateStepTypeCapture()) { + String value = captureNames.get(TSQueryPredicateStep.value_id(t)); + args.add(new TreeSitterQueryPredicateArg(value, TreeSitterQueryPredicateType.CAPTURE)); + log.info("XXX pattern steps - patternIndex={} type={} value={}", patternIndex, type, value); + } + else if (type == TreeSitter.TSQueryPredicateStepTypeString()) { + if (predicateValue == null) { + predicateValue = stringValues.get(TSQueryPredicateStep.value_id(t)); + } + else { + String value = stringValues.get(TSQueryPredicateStep.value_id(t)); + args.add(new TreeSitterQueryPredicateArg(value, TreeSitterQueryPredicateType.STRING)); + log.info("XXX pattern steps - patternIndex={} type={} value={}", patternIndex, type, value); + } + } + } + } + } + return predicates; + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQueryCapture.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQueryCapture.java new file mode 100644 index 000000000..6af7f13cb --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQueryCapture.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +/** + * + * @author Janne Valkealahti + */ +public class TreeSitterQueryCapture { + + private TreeSitterNode node; + private int index; + private String name; + + public TreeSitterQueryCapture(TreeSitterNode node, int index, String name) { + this.node = node; + this.index = index; + this.name = name; + } + + public TreeSitterNode getNode() { + return node; + } + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQueryMatch.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQueryMatch.java new file mode 100644 index 000000000..2a0506272 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterQueryMatch.java @@ -0,0 +1,59 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.util.List; + +/** + * + * @author Janne Valkealahti + */ +public class TreeSitterQueryMatch { + + private int id; + private int patternIndex; + private int captureCount; + private int captureIndex; + private List captures; + private List names; + + public TreeSitterQueryMatch(int id, int patternIndex, int captureIndex, int captureCount, + List captures, List names) { + this.id = id; + this.patternIndex = patternIndex; + this.captureIndex = captureIndex; + this.captureCount = captureCount; + this.captures = captures; + this.names = names; + } + + public int getPatternIndex() { + return patternIndex; + } + + public int getCaptureIndex() { + return captureIndex; + } + + public List getCaptures() { + return captures; + } + + public List getNames() { + return names; + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterServices.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterServices.java new file mode 100644 index 000000000..fa38cf411 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterServices.java @@ -0,0 +1,234 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.aot.AotServices; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; + +/** + * + * @author Janne Valkealahti + */ +public final class TreeSitterServices implements Iterable { + + /** + * The location to look for AOT factories. + */ + public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring/treesitter.factories"; + + private final List services; + + private final Map beans; + + private final Map sources; + + private TreeSitterServices(List loaded, Map beans) { + this.services = collectServices(loaded, beans); + this.sources = collectSources(loaded, beans.values()); + this.beans = beans; + } + + private List collectServices(List loaded, Map beans) { + List services = new ArrayList<>(); + services.addAll(beans.values()); + services.addAll(loaded); + AnnotationAwareOrderComparator.sort(services); + return Collections.unmodifiableList(services); + } + + private Map collectSources(Collection loaded, Collection beans) { + Map sources = new IdentityHashMap<>(); + loaded.forEach(service -> sources.put(service, Source.SPRING_FACTORIES_LOADER)); + beans.forEach(service -> sources.put(service, Source.BEAN_FACTORY)); + return Collections.unmodifiableMap(sources); + } + + /** + * Create a new {@link Loader} that will obtain AOT services from + * {@value #FACTORIES_RESOURCE_LOCATION}. + * @return a new {@link Loader} instance + */ + public static Loader factories() { + return factories((ClassLoader) null); + } + + /** + * Create a new {@link Loader} that will obtain AOT services from + * {@value #FACTORIES_RESOURCE_LOCATION}. + * @param classLoader the class loader used to load the factories resource + * @return a new {@link Loader} instance + */ + public static Loader factories(@Nullable ClassLoader classLoader) { + return factories(getSpringFactoriesLoader(classLoader)); + } + + /** + * Create a new {@link Loader} that will obtain AOT services from the given + * {@link SpringFactoriesLoader}. + * @param springFactoriesLoader the spring factories loader + * @return a new {@link Loader} instance + */ + public static Loader factories(SpringFactoriesLoader springFactoriesLoader) { + Assert.notNull(springFactoriesLoader, "'springFactoriesLoader' must not be null"); + return new Loader(springFactoriesLoader, null); + } + + /** + * Create a new {@link Loader} that will obtain AOT services from + * {@value #FACTORIES_RESOURCE_LOCATION} as well as the given + * {@link ListableBeanFactory}. + * @param beanFactory the bean factory + * @return a new {@link Loader} instance + */ + public static Loader factoriesAndBeans(ListableBeanFactory beanFactory) { + ClassLoader classLoader = (beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory ? + configurableBeanFactory.getBeanClassLoader() : null); + return factoriesAndBeans(getSpringFactoriesLoader(classLoader), beanFactory); + } + + /** + * Create a new {@link Loader} that will obtain AOT services from the given + * {@link SpringFactoriesLoader} and {@link ListableBeanFactory}. + * @param springFactoriesLoader the spring factories loader + * @param beanFactory the bean factory + * @return a new {@link Loader} instance + */ + public static Loader factoriesAndBeans(SpringFactoriesLoader springFactoriesLoader, ListableBeanFactory beanFactory) { + Assert.notNull(beanFactory, "'beanFactory' must not be null"); + Assert.notNull(springFactoriesLoader, "'springFactoriesLoader' must not be null"); + return new Loader(springFactoriesLoader, beanFactory); + } + + private static SpringFactoriesLoader getSpringFactoriesLoader( + @Nullable ClassLoader classLoader) { + return SpringFactoriesLoader.forResourceLocation(FACTORIES_RESOURCE_LOCATION, + classLoader); + } + + @Override + public Iterator iterator() { + return this.services.iterator(); + } + + /** + * Return a {@link Stream} of the AOT services. + * @return a stream of the services + */ + public Stream stream() { + return this.services.stream(); + } + + /** + * Return the AOT services as a {@link List}. + * @return a list of the services + */ + public List asList() { + return this.services; + } + + /** + * Find the AOT service that was loaded for the given bean name. + * @param beanName the bean name + * @return the AOT service or {@code null} + */ + @Nullable + public T findByBeanName(String beanName) { + return this.beans.get(beanName); + } + + /** + * Get the source of the given service. + * @param service the service instance + * @return the source of the service + */ + public Source getSource(T service) { + Source source = this.sources.get(service); + Assert.state(source != null, + () -> "Unable to find service " + ObjectUtils.identityToString(source)); + return source; + } + + + /** + * Loader class used to actually load the services. + */ + public static class Loader { + + private final SpringFactoriesLoader springFactoriesLoader; + + @Nullable + private final ListableBeanFactory beanFactory; + + + Loader(SpringFactoriesLoader springFactoriesLoader, @Nullable ListableBeanFactory beanFactory) { + this.springFactoriesLoader = springFactoriesLoader; + this.beanFactory = beanFactory; + } + + + /** + * Load all AOT services of the given type. + * @param the service type + * @param type the service type + * @return a new {@link AotServices} instance + */ + public TreeSitterServices load(Class type) { + return new TreeSitterServices<>(this.springFactoriesLoader.load(type), loadBeans(type)); + } + + private Map loadBeans(Class type) { + return (this.beanFactory != null) ? BeanFactoryUtils + .beansOfTypeIncludingAncestors(this.beanFactory, type, true, false) + : Collections.emptyMap(); + } + + } + + /** + * Sources from which services were obtained. + */ + public enum Source { + + /** + * An AOT service loaded from {@link SpringFactoriesLoader}. + */ + SPRING_FACTORIES_LOADER, + + /** + * An AOT service loaded from a {@link BeanFactory}. + */ + BEAN_FACTORY + + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterTree.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterTree.java new file mode 100644 index 000000000..a59f5edff --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/TreeSitterTree.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; + +import org.springframework.shell.treesitter.ts.TreeSitter; + +/** + * + * @author Janne Valkealahti + */ +public class TreeSitterTree { + + private MemorySegment tree; + private byte[] content; + + public TreeSitterTree(MemorySegment tree, byte[] content) { + this.tree = tree; + this.content = content; + } + + public TreeSitterNode getRootNode() { + Arena arena = Arena.ofShared(); + MemorySegment node = TreeSitter.ts_tree_root_node(arena, tree); + return TreeSitterNode.of(node, this); + } + + public byte[] getContent() { + return content; + } +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AbstractMatchTreeSitterQueryPredicate.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AbstractMatchTreeSitterQueryPredicate.java new file mode 100644 index 000000000..489eb0bae --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AbstractMatchTreeSitterQueryPredicate.java @@ -0,0 +1,96 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.shell.treesitter.TreeSitterNode; +import org.springframework.shell.treesitter.TreeSitterQueryMatch; +import org.springframework.shell.treesitter.TreeSitterTree; + +/** + * Base implementation of a {@code treesitter} {@code match} predicates. + * + * @author Janne Valkealahti + */ +abstract class AbstractMatchTreeSitterQueryPredicate extends AbstractTreeSitterQueryPredicate { + + private String capture; + private List patterns; + private boolean matchAll = false; + private boolean negate = false; + + AbstractMatchTreeSitterQueryPredicate(String capture, Pattern pattern, boolean matchAll, boolean negate) { + this(capture, List.of(pattern), matchAll, negate); + } + + AbstractMatchTreeSitterQueryPredicate(String capture, List patterns, boolean matchAll, boolean negate) { + this.capture = capture; + this.patterns = patterns; + this.matchAll = matchAll; + this.negate = negate; + } + + @Override + protected boolean testInternal(TreeSitterQueryPredicateContext context) { + TreeSitterQueryMatch match = context.match(); + + List nodes = match.getCaptures().stream() + .filter(c -> c.getName().equals(capture)) + .map(c -> c.getNode()) + .collect(Collectors.toList()) + ; + + boolean present = nodes.stream() + .filter(n -> { + TreeSitterTree tree = n.getTree(); + byte[] xxx = new byte[n.getEndByte() - n.getStartByte()]; + System.arraycopy(tree.getContent(), n.getStartByte(), xxx, 0, xxx.length); + String ddd = new String(xxx); + boolean matches = patternMatch(ddd); + return matches; + }) + .findFirst() + .isPresent() + ; + + if (!negate) { + return present; + } + else { + return !present; + } + } + + private boolean patternMatch(String text) { + Stream pStream = patterns.stream(); + if (matchAll) { + return pStream.allMatch(x -> x.matcher(text).matches()); + } + else { + return pStream.anyMatch(x -> x.matcher(text).matches()); + } + } + + @Override + public String toString() { + return "[capture=" + capture + ", patterns=" + patterns + ", matchAll=" + matchAll + ", negate=" + negate + "]"; + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AbstractTreeSitterQueryPredicate.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AbstractTreeSitterQueryPredicate.java new file mode 100644 index 000000000..1b0db57a7 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AbstractTreeSitterQueryPredicate.java @@ -0,0 +1,26 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +abstract class AbstractTreeSitterQueryPredicate implements TreeSitterQueryPredicate { + + @Override + public final boolean test(TreeSitterQueryPredicateContext context) { + return testInternal(context); + } + + protected abstract boolean testInternal(TreeSitterQueryPredicateContext context); +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AnyMatchTreeSitterQueryPredicate.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AnyMatchTreeSitterQueryPredicate.java new file mode 100644 index 000000000..8e485c5f4 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AnyMatchTreeSitterQueryPredicate.java @@ -0,0 +1,32 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.regex.Pattern; + +/** + * Implementation of a {@code treesitter} {@code any-match} predicate. + * + * @author Janne Valkealahti + */ +class AnyMatchTreeSitterQueryPredicate extends AbstractMatchTreeSitterQueryPredicate { + + AnyMatchTreeSitterQueryPredicate(String capture, List patterns) { + super(capture, patterns, false, false); + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AnyNotMatchTreeSitterQueryPredicate.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AnyNotMatchTreeSitterQueryPredicate.java new file mode 100644 index 000000000..6cd427331 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/AnyNotMatchTreeSitterQueryPredicate.java @@ -0,0 +1,32 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.regex.Pattern; + +/** + * Implementation of a {@code treesitter} {@code any-not-match} predicate. + * + * @author Janne Valkealahti + */ +public class AnyNotMatchTreeSitterQueryPredicate extends AbstractMatchTreeSitterQueryPredicate { + + AnyNotMatchTreeSitterQueryPredicate(String capture, List patterns) { + super(capture, patterns, true, true); + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/MatchTreeSitterQueryPredicate.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/MatchTreeSitterQueryPredicate.java new file mode 100644 index 000000000..2af8b2136 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/MatchTreeSitterQueryPredicate.java @@ -0,0 +1,50 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.regex.Pattern; + +/** + * Implementation of a {@code treesitter} {@code match} predicate. + * + * @author Janne Valkealahti + */ +public class MatchTreeSitterQueryPredicate extends AbstractMatchTreeSitterQueryPredicate { + + public final static String PREDICATE = "match?"; + + public MatchTreeSitterQueryPredicate(String capture, Pattern pattern) { + super(capture, pattern, true, false); + } + + public static MatchTreeSitterQueryPredicate of(List args) { + if (args.size() == 2) { + TreeSitterQueryPredicateArg captureArg = args.get(0); + TreeSitterQueryPredicateArg patternArg = args.get(1); + return new MatchTreeSitterQueryPredicate(captureArg.value(), Pattern.compile(patternArg.value())); + } + else { + throw new IllegalArgumentException(); + } + } + + @Override + public String toString() { + return "MatchTreeSitterQueryPredicate [%s]".formatted(super.toString()); + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/NotMatchTreeSitterQueryPredicate.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/NotMatchTreeSitterQueryPredicate.java new file mode 100644 index 000000000..a33ec25a1 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/NotMatchTreeSitterQueryPredicate.java @@ -0,0 +1,31 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.regex.Pattern; + +/** + * Implementation of a {@code treesitter} {@code not-match} predicate. + * + * @author Janne Valkealahti + */ +class NotMatchTreeSitterQueryPredicate extends AbstractMatchTreeSitterQueryPredicate { + + NotMatchTreeSitterQueryPredicate(String capture, Pattern pattern) { + super(capture, pattern, true, true); + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/TreeSitterQueryPredicate.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/TreeSitterQueryPredicate.java new file mode 100644 index 000000000..308f1fd59 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/predicate/TreeSitterQueryPredicate.java @@ -0,0 +1,40 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.function.Predicate; + +import org.springframework.shell.treesitter.TreeSitterQueryMatch; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateContext; + +public interface TreeSitterQueryPredicate extends Predicate { + + record TreeSitterQueryPredicateContext(TreeSitterQueryMatch match) { + } + + enum TreeSitterQueryPredicateType { + CAPTURE, + STRING; + } + + record TreeSitterQueryPredicateArg(String value, TreeSitterQueryPredicateType type) { + } + + record TreeSitterQueryPredicateDefinition(String value, List args) { + } + +} diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSInput.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSInput.java new file mode 100644 index 000000000..1aa92c12d --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSInput.java @@ -0,0 +1,277 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSInput { + * void *payload; + * const char *(*read)(void *, uint32_t, TSPoint, uint32_t *); + * TSInputEncoding encoding; + * } + * } + */ +public class TSInput { + + TSInput() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TreeSitter.C_POINTER.withName("payload"), + TreeSitter.C_POINTER.withName("read"), + TreeSitter.C_INT.withName("encoding"), + MemoryLayout.paddingLayout(4) + ).withName("TSInput"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final AddressLayout payload$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("payload")); + + /** + * Layout for field: + * {@snippet lang=c : + * void *payload + * } + */ + public static final AddressLayout payload$layout() { + return payload$LAYOUT; + } + + private static final long payload$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * void *payload + * } + */ + public static final long payload$offset() { + return payload$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * void *payload + * } + */ + public static MemorySegment payload(MemorySegment struct) { + return struct.get(payload$LAYOUT, payload$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * void *payload + * } + */ + public static void payload(MemorySegment struct, MemorySegment fieldValue) { + struct.set(payload$LAYOUT, payload$OFFSET, fieldValue); + } + + /** + * {@snippet lang=c : + * const char *(*read)(void *, uint32_t, TSPoint, uint32_t *) + * } + */ + public static class read { + + read() { + // Should not be called directly + } + + /** + * The function pointer signature, expressed as a functional interface + */ + public interface Function { + MemorySegment apply(MemorySegment _x0, int _x1, MemorySegment _x2, MemorySegment _x3); + } + + private static final FunctionDescriptor $DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TSPoint.layout(), + TreeSitter.C_POINTER + ); + + /** + * The descriptor of this function pointer + */ + public static FunctionDescriptor descriptor() { + return $DESC; + } + + private static final MethodHandle UP$MH = TreeSitter.upcallHandle(read.Function.class, "apply", $DESC); + + /** + * Allocates a new upcall stub, whose implementation is defined by {@code fi}. + * The lifetime of the returned segment is managed by {@code arena} + */ + public static MemorySegment allocate(read.Function fi, Arena arena) { + return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); + } + + private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); + + /** + * Invoke the upcall stub {@code funcPtr}, with given parameters + */ + public static MemorySegment invoke(MemorySegment funcPtr,MemorySegment _x0, int _x1, MemorySegment _x2, MemorySegment _x3) { + try { + return (MemorySegment) DOWN$MH.invokeExact(funcPtr, _x0, _x1, _x2, _x3); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + } + + private static final AddressLayout read$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("read")); + + /** + * Layout for field: + * {@snippet lang=c : + * const char *(*read)(void *, uint32_t, TSPoint, uint32_t *) + * } + */ + public static final AddressLayout read$layout() { + return read$LAYOUT; + } + + private static final long read$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * const char *(*read)(void *, uint32_t, TSPoint, uint32_t *) + * } + */ + public static final long read$offset() { + return read$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * const char *(*read)(void *, uint32_t, TSPoint, uint32_t *) + * } + */ + public static MemorySegment read(MemorySegment struct) { + return struct.get(read$LAYOUT, read$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * const char *(*read)(void *, uint32_t, TSPoint, uint32_t *) + * } + */ + public static void read(MemorySegment struct, MemorySegment fieldValue) { + struct.set(read$LAYOUT, read$OFFSET, fieldValue); + } + + private static final OfInt encoding$LAYOUT = (OfInt)$LAYOUT.select(groupElement("encoding")); + + /** + * Layout for field: + * {@snippet lang=c : + * TSInputEncoding encoding + * } + */ + public static final OfInt encoding$layout() { + return encoding$LAYOUT; + } + + private static final long encoding$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang=c : + * TSInputEncoding encoding + * } + */ + public static final long encoding$offset() { + return encoding$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * TSInputEncoding encoding + * } + */ + public static int encoding(MemorySegment struct) { + return struct.get(encoding$LAYOUT, encoding$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * TSInputEncoding encoding + * } + */ + public static void encoding(MemorySegment struct, int fieldValue) { + struct.set(encoding$LAYOUT, encoding$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSInputEdit.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSInputEdit.java new file mode 100644 index 000000000..3e74bf0f6 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSInputEdit.java @@ -0,0 +1,357 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSInputEdit { + * uint32_t start_byte; + * uint32_t old_end_byte; + * uint32_t new_end_byte; + * TSPoint start_point; + * TSPoint old_end_point; + * TSPoint new_end_point; + * } + * } + */ +public class TSInputEdit { + + TSInputEdit() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TreeSitter.C_INT.withName("start_byte"), + TreeSitter.C_INT.withName("old_end_byte"), + TreeSitter.C_INT.withName("new_end_byte"), + TSPoint.layout().withName("start_point"), + TSPoint.layout().withName("old_end_point"), + TSPoint.layout().withName("new_end_point") + ).withName("TSInputEdit"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt start_byte$LAYOUT = (OfInt)$LAYOUT.select(groupElement("start_byte")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t start_byte + * } + */ + public static final OfInt start_byte$layout() { + return start_byte$LAYOUT; + } + + private static final long start_byte$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t start_byte + * } + */ + public static final long start_byte$offset() { + return start_byte$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t start_byte + * } + */ + public static int start_byte(MemorySegment struct) { + return struct.get(start_byte$LAYOUT, start_byte$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t start_byte + * } + */ + public static void start_byte(MemorySegment struct, int fieldValue) { + struct.set(start_byte$LAYOUT, start_byte$OFFSET, fieldValue); + } + + private static final OfInt old_end_byte$LAYOUT = (OfInt)$LAYOUT.select(groupElement("old_end_byte")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t old_end_byte + * } + */ + public static final OfInt old_end_byte$layout() { + return old_end_byte$LAYOUT; + } + + private static final long old_end_byte$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t old_end_byte + * } + */ + public static final long old_end_byte$offset() { + return old_end_byte$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t old_end_byte + * } + */ + public static int old_end_byte(MemorySegment struct) { + return struct.get(old_end_byte$LAYOUT, old_end_byte$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t old_end_byte + * } + */ + public static void old_end_byte(MemorySegment struct, int fieldValue) { + struct.set(old_end_byte$LAYOUT, old_end_byte$OFFSET, fieldValue); + } + + private static final OfInt new_end_byte$LAYOUT = (OfInt)$LAYOUT.select(groupElement("new_end_byte")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t new_end_byte + * } + */ + public static final OfInt new_end_byte$layout() { + return new_end_byte$LAYOUT; + } + + private static final long new_end_byte$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t new_end_byte + * } + */ + public static final long new_end_byte$offset() { + return new_end_byte$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t new_end_byte + * } + */ + public static int new_end_byte(MemorySegment struct) { + return struct.get(new_end_byte$LAYOUT, new_end_byte$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t new_end_byte + * } + */ + public static void new_end_byte(MemorySegment struct, int fieldValue) { + struct.set(new_end_byte$LAYOUT, new_end_byte$OFFSET, fieldValue); + } + + private static final GroupLayout start_point$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("start_point")); + + /** + * Layout for field: + * {@snippet lang=c : + * TSPoint start_point + * } + */ + public static final GroupLayout start_point$layout() { + return start_point$LAYOUT; + } + + private static final long start_point$OFFSET = 12; + + /** + * Offset for field: + * {@snippet lang=c : + * TSPoint start_point + * } + */ + public static final long start_point$offset() { + return start_point$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * TSPoint start_point + * } + */ + public static MemorySegment start_point(MemorySegment struct) { + return struct.asSlice(start_point$OFFSET, start_point$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * TSPoint start_point + * } + */ + public static void start_point(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, start_point$OFFSET, start_point$LAYOUT.byteSize()); + } + + private static final GroupLayout old_end_point$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("old_end_point")); + + /** + * Layout for field: + * {@snippet lang=c : + * TSPoint old_end_point + * } + */ + public static final GroupLayout old_end_point$layout() { + return old_end_point$LAYOUT; + } + + private static final long old_end_point$OFFSET = 20; + + /** + * Offset for field: + * {@snippet lang=c : + * TSPoint old_end_point + * } + */ + public static final long old_end_point$offset() { + return old_end_point$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * TSPoint old_end_point + * } + */ + public static MemorySegment old_end_point(MemorySegment struct) { + return struct.asSlice(old_end_point$OFFSET, old_end_point$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * TSPoint old_end_point + * } + */ + public static void old_end_point(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, old_end_point$OFFSET, old_end_point$LAYOUT.byteSize()); + } + + private static final GroupLayout new_end_point$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("new_end_point")); + + /** + * Layout for field: + * {@snippet lang=c : + * TSPoint new_end_point + * } + */ + public static final GroupLayout new_end_point$layout() { + return new_end_point$LAYOUT; + } + + private static final long new_end_point$OFFSET = 28; + + /** + * Offset for field: + * {@snippet lang=c : + * TSPoint new_end_point + * } + */ + public static final long new_end_point$offset() { + return new_end_point$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * TSPoint new_end_point + * } + */ + public static MemorySegment new_end_point(MemorySegment struct) { + return struct.asSlice(new_end_point$OFFSET, new_end_point$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * TSPoint new_end_point + * } + */ + public static void new_end_point(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, new_end_point$OFFSET, new_end_point$LAYOUT.byteSize()); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSLogger.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSLogger.java new file mode 100644 index 000000000..019e81a62 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSLogger.java @@ -0,0 +1,228 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSLogger { + * void *payload; + * void (*log)(void *, TSLogType, const char *); + * } + * } + */ +public class TSLogger { + + TSLogger() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TreeSitter.C_POINTER.withName("payload"), + TreeSitter.C_POINTER.withName("log") + ).withName("TSLogger"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final AddressLayout payload$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("payload")); + + /** + * Layout for field: + * {@snippet lang=c : + * void *payload + * } + */ + public static final AddressLayout payload$layout() { + return payload$LAYOUT; + } + + private static final long payload$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * void *payload + * } + */ + public static final long payload$offset() { + return payload$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * void *payload + * } + */ + public static MemorySegment payload(MemorySegment struct) { + return struct.get(payload$LAYOUT, payload$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * void *payload + * } + */ + public static void payload(MemorySegment struct, MemorySegment fieldValue) { + struct.set(payload$LAYOUT, payload$OFFSET, fieldValue); + } + + /** + * {@snippet lang=c : + * void (*log)(void *, TSLogType, const char *) + * } + */ + public static class log { + + log() { + // Should not be called directly + } + + /** + * The function pointer signature, expressed as a functional interface + */ + public interface Function { + void apply(MemorySegment _x0, int _x1, MemorySegment _x2); + } + + private static final FunctionDescriptor $DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + /** + * The descriptor of this function pointer + */ + public static FunctionDescriptor descriptor() { + return $DESC; + } + + private static final MethodHandle UP$MH = TreeSitter.upcallHandle(log.Function.class, "apply", $DESC); + + /** + * Allocates a new upcall stub, whose implementation is defined by {@code fi}. + * The lifetime of the returned segment is managed by {@code arena} + */ + public static MemorySegment allocate(log.Function fi, Arena arena) { + return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); + } + + private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); + + /** + * Invoke the upcall stub {@code funcPtr}, with given parameters + */ + public static void invoke(MemorySegment funcPtr,MemorySegment _x0, int _x1, MemorySegment _x2) { + try { + DOWN$MH.invokeExact(funcPtr, _x0, _x1, _x2); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + } + + private static final AddressLayout log$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("log")); + + /** + * Layout for field: + * {@snippet lang=c : + * void (*log)(void *, TSLogType, const char *) + * } + */ + public static final AddressLayout log$layout() { + return log$LAYOUT; + } + + private static final long log$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * void (*log)(void *, TSLogType, const char *) + * } + */ + public static final long log$offset() { + return log$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * void (*log)(void *, TSLogType, const char *) + * } + */ + public static MemorySegment log(MemorySegment struct) { + return struct.get(log$LAYOUT, log$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * void (*log)(void *, TSLogType, const char *) + * } + */ + public static void log(MemorySegment struct, MemorySegment fieldValue) { + struct.set(log$LAYOUT, log$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSNode.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSNode.java new file mode 100644 index 000000000..a78798810 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSNode.java @@ -0,0 +1,252 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSNode { + * uint32_t context[4]; + * const void *id; + * const TSTree *tree; + * } + * } + */ +public class TSNode { + + TSNode() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + MemoryLayout.sequenceLayout(4, TreeSitter.C_INT).withName("context"), + TreeSitter.C_POINTER.withName("id"), + TreeSitter.C_POINTER.withName("tree") + ).withName("TSNode"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final SequenceLayout context$LAYOUT = (SequenceLayout)$LAYOUT.select(groupElement("context")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t context[4] + * } + */ + public static final SequenceLayout context$layout() { + return context$LAYOUT; + } + + private static final long context$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t context[4] + * } + */ + public static final long context$offset() { + return context$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t context[4] + * } + */ + public static MemorySegment context(MemorySegment struct) { + return struct.asSlice(context$OFFSET, context$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t context[4] + * } + */ + public static void context(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, context$OFFSET, context$LAYOUT.byteSize()); + } + + private static long[] context$DIMS = { 4 }; + + /** + * Dimensions for array field: + * {@snippet lang=c : + * uint32_t context[4] + * } + */ + public static long[] context$dimensions() { + return context$DIMS; + } + private static final VarHandle context$ELEM_HANDLE = context$LAYOUT.varHandle(sequenceElement()); + + /** + * Indexed getter for field: + * {@snippet lang=c : + * uint32_t context[4] + * } + */ + public static int context(MemorySegment struct, long index0) { + return (int)context$ELEM_HANDLE.get(struct, 0L, index0); + } + + /** + * Indexed setter for field: + * {@snippet lang=c : + * uint32_t context[4] + * } + */ + public static void context(MemorySegment struct, long index0, int fieldValue) { + context$ELEM_HANDLE.set(struct, 0L, index0, fieldValue); + } + + private static final AddressLayout id$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("id")); + + /** + * Layout for field: + * {@snippet lang=c : + * const void *id + * } + */ + public static final AddressLayout id$layout() { + return id$LAYOUT; + } + + private static final long id$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang=c : + * const void *id + * } + */ + public static final long id$offset() { + return id$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * const void *id + * } + */ + public static MemorySegment id(MemorySegment struct) { + return struct.get(id$LAYOUT, id$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * const void *id + * } + */ + public static void id(MemorySegment struct, MemorySegment fieldValue) { + struct.set(id$LAYOUT, id$OFFSET, fieldValue); + } + + private static final AddressLayout tree$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("tree")); + + /** + * Layout for field: + * {@snippet lang=c : + * const TSTree *tree + * } + */ + public static final AddressLayout tree$layout() { + return tree$LAYOUT; + } + + private static final long tree$OFFSET = 24; + + /** + * Offset for field: + * {@snippet lang=c : + * const TSTree *tree + * } + */ + public static final long tree$offset() { + return tree$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * const TSTree *tree + * } + */ + public static MemorySegment tree(MemorySegment struct) { + return struct.get(tree$LAYOUT, tree$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * const TSTree *tree + * } + */ + public static void tree(MemorySegment struct, MemorySegment fieldValue) { + struct.set(tree$LAYOUT, tree$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSPoint.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSPoint.java new file mode 100644 index 000000000..0cbfb5a14 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSPoint.java @@ -0,0 +1,173 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSPoint { + * uint32_t row; + * uint32_t column; + * } + * } + */ +public class TSPoint { + + TSPoint() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TreeSitter.C_INT.withName("row"), + TreeSitter.C_INT.withName("column") + ).withName("TSPoint"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt row$LAYOUT = (OfInt)$LAYOUT.select(groupElement("row")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t row + * } + */ + public static final OfInt row$layout() { + return row$LAYOUT; + } + + private static final long row$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t row + * } + */ + public static final long row$offset() { + return row$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t row + * } + */ + public static int row(MemorySegment struct) { + return struct.get(row$LAYOUT, row$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t row + * } + */ + public static void row(MemorySegment struct, int fieldValue) { + struct.set(row$LAYOUT, row$OFFSET, fieldValue); + } + + private static final OfInt column$LAYOUT = (OfInt)$LAYOUT.select(groupElement("column")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t column + * } + */ + public static final OfInt column$layout() { + return column$LAYOUT; + } + + private static final long column$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t column + * } + */ + public static final long column$offset() { + return column$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t column + * } + */ + public static int column(MemorySegment struct) { + return struct.get(column$LAYOUT, column$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t column + * } + */ + public static void column(MemorySegment struct, int fieldValue) { + struct.set(column$LAYOUT, column$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryCapture.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryCapture.java new file mode 100644 index 000000000..7334b20f2 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryCapture.java @@ -0,0 +1,174 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSQueryCapture { + * TSNode node; + * uint32_t index; + * } + * } + */ +public class TSQueryCapture { + + TSQueryCapture() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TSNode.layout().withName("node"), + TreeSitter.C_INT.withName("index"), + MemoryLayout.paddingLayout(4) + ).withName("TSQueryCapture"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final GroupLayout node$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("node")); + + /** + * Layout for field: + * {@snippet lang=c : + * TSNode node + * } + */ + public static final GroupLayout node$layout() { + return node$LAYOUT; + } + + private static final long node$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * TSNode node + * } + */ + public static final long node$offset() { + return node$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * TSNode node + * } + */ + public static MemorySegment node(MemorySegment struct) { + return struct.asSlice(node$OFFSET, node$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * TSNode node + * } + */ + public static void node(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, node$OFFSET, node$LAYOUT.byteSize()); + } + + private static final OfInt index$LAYOUT = (OfInt)$LAYOUT.select(groupElement("index")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t index + * } + */ + public static final OfInt index$layout() { + return index$LAYOUT; + } + + private static final long index$OFFSET = 32; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t index + * } + */ + public static final long index$offset() { + return index$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t index + * } + */ + public static int index(MemorySegment struct) { + return struct.get(index$LAYOUT, index$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t index + * } + */ + public static void index(MemorySegment struct, int fieldValue) { + struct.set(index$LAYOUT, index$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryMatch.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryMatch.java new file mode 100644 index 000000000..15ee40471 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryMatch.java @@ -0,0 +1,265 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSQueryMatch { + * uint32_t id; + * uint16_t pattern_index; + * uint16_t capture_count; + * const TSQueryCapture *captures; + * } + * } + */ +public class TSQueryMatch { + + TSQueryMatch() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TreeSitter.C_INT.withName("id"), + TreeSitter.C_SHORT.withName("pattern_index"), + TreeSitter.C_SHORT.withName("capture_count"), + TreeSitter.C_POINTER.withName("captures") + ).withName("TSQueryMatch"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt id$LAYOUT = (OfInt)$LAYOUT.select(groupElement("id")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t id + * } + */ + public static final OfInt id$layout() { + return id$LAYOUT; + } + + private static final long id$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t id + * } + */ + public static final long id$offset() { + return id$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t id + * } + */ + public static int id(MemorySegment struct) { + return struct.get(id$LAYOUT, id$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t id + * } + */ + public static void id(MemorySegment struct, int fieldValue) { + struct.set(id$LAYOUT, id$OFFSET, fieldValue); + } + + private static final OfShort pattern_index$LAYOUT = (OfShort)$LAYOUT.select(groupElement("pattern_index")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint16_t pattern_index + * } + */ + public static final OfShort pattern_index$layout() { + return pattern_index$LAYOUT; + } + + private static final long pattern_index$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang=c : + * uint16_t pattern_index + * } + */ + public static final long pattern_index$offset() { + return pattern_index$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint16_t pattern_index + * } + */ + public static short pattern_index(MemorySegment struct) { + return struct.get(pattern_index$LAYOUT, pattern_index$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint16_t pattern_index + * } + */ + public static void pattern_index(MemorySegment struct, short fieldValue) { + struct.set(pattern_index$LAYOUT, pattern_index$OFFSET, fieldValue); + } + + private static final OfShort capture_count$LAYOUT = (OfShort)$LAYOUT.select(groupElement("capture_count")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint16_t capture_count + * } + */ + public static final OfShort capture_count$layout() { + return capture_count$LAYOUT; + } + + private static final long capture_count$OFFSET = 6; + + /** + * Offset for field: + * {@snippet lang=c : + * uint16_t capture_count + * } + */ + public static final long capture_count$offset() { + return capture_count$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint16_t capture_count + * } + */ + public static short capture_count(MemorySegment struct) { + return struct.get(capture_count$LAYOUT, capture_count$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint16_t capture_count + * } + */ + public static void capture_count(MemorySegment struct, short fieldValue) { + struct.set(capture_count$LAYOUT, capture_count$OFFSET, fieldValue); + } + + private static final AddressLayout captures$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("captures")); + + /** + * Layout for field: + * {@snippet lang=c : + * const TSQueryCapture *captures + * } + */ + public static final AddressLayout captures$layout() { + return captures$LAYOUT; + } + + private static final long captures$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * const TSQueryCapture *captures + * } + */ + public static final long captures$offset() { + return captures$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * const TSQueryCapture *captures + * } + */ + public static MemorySegment captures(MemorySegment struct) { + return struct.get(captures$LAYOUT, captures$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * const TSQueryCapture *captures + * } + */ + public static void captures(MemorySegment struct, MemorySegment fieldValue) { + struct.set(captures$LAYOUT, captures$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryPredicateStep.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryPredicateStep.java new file mode 100644 index 000000000..cf66ace00 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSQueryPredicateStep.java @@ -0,0 +1,173 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSQueryPredicateStep { + * TSQueryPredicateStepType type; + * uint32_t value_id; + * } + * } + */ +public class TSQueryPredicateStep { + + TSQueryPredicateStep() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TreeSitter.C_INT.withName("type"), + TreeSitter.C_INT.withName("value_id") + ).withName("TSQueryPredicateStep"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final OfInt type$LAYOUT = (OfInt)$LAYOUT.select(groupElement("type")); + + /** + * Layout for field: + * {@snippet lang=c : + * TSQueryPredicateStepType type + * } + */ + public static final OfInt type$layout() { + return type$LAYOUT; + } + + private static final long type$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * TSQueryPredicateStepType type + * } + */ + public static final long type$offset() { + return type$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * TSQueryPredicateStepType type + * } + */ + public static int type(MemorySegment struct) { + return struct.get(type$LAYOUT, type$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * TSQueryPredicateStepType type + * } + */ + public static void type(MemorySegment struct, int fieldValue) { + struct.set(type$LAYOUT, type$OFFSET, fieldValue); + } + + private static final OfInt value_id$LAYOUT = (OfInt)$LAYOUT.select(groupElement("value_id")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t value_id + * } + */ + public static final OfInt value_id$layout() { + return value_id$LAYOUT; + } + + private static final long value_id$OFFSET = 4; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t value_id + * } + */ + public static final long value_id$offset() { + return value_id$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t value_id + * } + */ + public static int value_id(MemorySegment struct) { + return struct.get(value_id$LAYOUT, value_id$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t value_id + * } + */ + public static void value_id(MemorySegment struct, int fieldValue) { + struct.set(value_id$LAYOUT, value_id$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSRange.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSRange.java new file mode 100644 index 000000000..1916f6b74 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSRange.java @@ -0,0 +1,265 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSRange { + * TSPoint start_point; + * TSPoint end_point; + * uint32_t start_byte; + * uint32_t end_byte; + * } + * } + */ +public class TSRange { + + TSRange() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TSPoint.layout().withName("start_point"), + TSPoint.layout().withName("end_point"), + TreeSitter.C_INT.withName("start_byte"), + TreeSitter.C_INT.withName("end_byte") + ).withName("TSRange"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final GroupLayout start_point$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("start_point")); + + /** + * Layout for field: + * {@snippet lang=c : + * TSPoint start_point + * } + */ + public static final GroupLayout start_point$layout() { + return start_point$LAYOUT; + } + + private static final long start_point$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * TSPoint start_point + * } + */ + public static final long start_point$offset() { + return start_point$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * TSPoint start_point + * } + */ + public static MemorySegment start_point(MemorySegment struct) { + return struct.asSlice(start_point$OFFSET, start_point$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * TSPoint start_point + * } + */ + public static void start_point(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, start_point$OFFSET, start_point$LAYOUT.byteSize()); + } + + private static final GroupLayout end_point$LAYOUT = (GroupLayout)$LAYOUT.select(groupElement("end_point")); + + /** + * Layout for field: + * {@snippet lang=c : + * TSPoint end_point + * } + */ + public static final GroupLayout end_point$layout() { + return end_point$LAYOUT; + } + + private static final long end_point$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * TSPoint end_point + * } + */ + public static final long end_point$offset() { + return end_point$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * TSPoint end_point + * } + */ + public static MemorySegment end_point(MemorySegment struct) { + return struct.asSlice(end_point$OFFSET, end_point$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * TSPoint end_point + * } + */ + public static void end_point(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, end_point$OFFSET, end_point$LAYOUT.byteSize()); + } + + private static final OfInt start_byte$LAYOUT = (OfInt)$LAYOUT.select(groupElement("start_byte")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t start_byte + * } + */ + public static final OfInt start_byte$layout() { + return start_byte$LAYOUT; + } + + private static final long start_byte$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t start_byte + * } + */ + public static final long start_byte$offset() { + return start_byte$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t start_byte + * } + */ + public static int start_byte(MemorySegment struct) { + return struct.get(start_byte$LAYOUT, start_byte$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t start_byte + * } + */ + public static void start_byte(MemorySegment struct, int fieldValue) { + struct.set(start_byte$LAYOUT, start_byte$OFFSET, fieldValue); + } + + private static final OfInt end_byte$LAYOUT = (OfInt)$LAYOUT.select(groupElement("end_byte")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t end_byte + * } + */ + public static final OfInt end_byte$layout() { + return end_byte$LAYOUT; + } + + private static final long end_byte$OFFSET = 20; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t end_byte + * } + */ + public static final long end_byte$offset() { + return end_byte$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t end_byte + * } + */ + public static int end_byte(MemorySegment struct) { + return struct.get(end_byte$LAYOUT, end_byte$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t end_byte + * } + */ + public static void end_byte(MemorySegment struct, int fieldValue) { + struct.set(end_byte$LAYOUT, end_byte$OFFSET, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSTreeCursor.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSTreeCursor.java new file mode 100644 index 000000000..f5ad7508c --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TSTreeCursor.java @@ -0,0 +1,253 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +/** + * {@snippet lang=c : + * struct TSTreeCursor { + * const void *tree; + * const void *id; + * uint32_t context[3]; + * } + * } + */ +public class TSTreeCursor { + + TSTreeCursor() { + // Should not be called directly + } + + private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( + TreeSitter.C_POINTER.withName("tree"), + TreeSitter.C_POINTER.withName("id"), + MemoryLayout.sequenceLayout(3, TreeSitter.C_INT).withName("context"), + MemoryLayout.paddingLayout(4) + ).withName("TSTreeCursor"); + + /** + * The layout of this struct + */ + public static final GroupLayout layout() { + return $LAYOUT; + } + + private static final AddressLayout tree$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("tree")); + + /** + * Layout for field: + * {@snippet lang=c : + * const void *tree + * } + */ + public static final AddressLayout tree$layout() { + return tree$LAYOUT; + } + + private static final long tree$OFFSET = 0; + + /** + * Offset for field: + * {@snippet lang=c : + * const void *tree + * } + */ + public static final long tree$offset() { + return tree$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * const void *tree + * } + */ + public static MemorySegment tree(MemorySegment struct) { + return struct.get(tree$LAYOUT, tree$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * const void *tree + * } + */ + public static void tree(MemorySegment struct, MemorySegment fieldValue) { + struct.set(tree$LAYOUT, tree$OFFSET, fieldValue); + } + + private static final AddressLayout id$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("id")); + + /** + * Layout for field: + * {@snippet lang=c : + * const void *id + * } + */ + public static final AddressLayout id$layout() { + return id$LAYOUT; + } + + private static final long id$OFFSET = 8; + + /** + * Offset for field: + * {@snippet lang=c : + * const void *id + * } + */ + public static final long id$offset() { + return id$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * const void *id + * } + */ + public static MemorySegment id(MemorySegment struct) { + return struct.get(id$LAYOUT, id$OFFSET); + } + + /** + * Setter for field: + * {@snippet lang=c : + * const void *id + * } + */ + public static void id(MemorySegment struct, MemorySegment fieldValue) { + struct.set(id$LAYOUT, id$OFFSET, fieldValue); + } + + private static final SequenceLayout context$LAYOUT = (SequenceLayout)$LAYOUT.select(groupElement("context")); + + /** + * Layout for field: + * {@snippet lang=c : + * uint32_t context[3] + * } + */ + public static final SequenceLayout context$layout() { + return context$LAYOUT; + } + + private static final long context$OFFSET = 16; + + /** + * Offset for field: + * {@snippet lang=c : + * uint32_t context[3] + * } + */ + public static final long context$offset() { + return context$OFFSET; + } + + /** + * Getter for field: + * {@snippet lang=c : + * uint32_t context[3] + * } + */ + public static MemorySegment context(MemorySegment struct) { + return struct.asSlice(context$OFFSET, context$LAYOUT.byteSize()); + } + + /** + * Setter for field: + * {@snippet lang=c : + * uint32_t context[3] + * } + */ + public static void context(MemorySegment struct, MemorySegment fieldValue) { + MemorySegment.copy(fieldValue, 0L, struct, context$OFFSET, context$LAYOUT.byteSize()); + } + + private static long[] context$DIMS = { 3 }; + + /** + * Dimensions for array field: + * {@snippet lang=c : + * uint32_t context[3] + * } + */ + public static long[] context$dimensions() { + return context$DIMS; + } + private static final VarHandle context$ELEM_HANDLE = context$LAYOUT.varHandle(sequenceElement()); + + /** + * Indexed getter for field: + * {@snippet lang=c : + * uint32_t context[3] + * } + */ + public static int context(MemorySegment struct, long index0) { + return (int)context$ELEM_HANDLE.get(struct, 0L, index0); + } + + /** + * Indexed setter for field: + * {@snippet lang=c : + * uint32_t context[3] + * } + */ + public static void context(MemorySegment struct, long index0, int fieldValue) { + context$ELEM_HANDLE.set(struct, 0L, index0, fieldValue); + } + + /** + * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. + * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} + */ + public static MemorySegment asSlice(MemorySegment array, long index) { + return array.asSlice(layout().byteSize() * index); + } + + /** + * The size (in bytes) of this struct + */ + public static long sizeof() { return layout().byteSize(); } + + /** + * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} + */ + public static MemorySegment allocate(SegmentAllocator allocator) { + return allocator.allocate(layout()); + } + + /** + * Allocate an array of size {@code elementCount} using {@code allocator}. + * The returned segment has size {@code elementCount * layout().byteSize()}. + */ + public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { + return reinterpret(addr, 1, arena, cleanup); + } + + /** + * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). + * The returned segment has size {@code elementCount * layout().byteSize()} + */ + public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { + return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); + } +} + diff --git a/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TreeSitter.java b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TreeSitter.java new file mode 100644 index 000000000..96a0585e4 --- /dev/null +++ b/spring-shell-treesitter/src/main/java/org/springframework/shell/treesitter/ts/TreeSitter.java @@ -0,0 +1,8123 @@ +// Generated by jextract + +package org.springframework.shell.treesitter.ts; + +import java.lang.invoke.*; +import java.lang.foreign.*; +import java.nio.ByteOrder; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.MemoryLayout.PathElement.*; + +public class TreeSitter { + + TreeSitter() { + // Should not be called directly + } + + static final Arena LIBRARY_ARENA = Arena.ofAuto(); + static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls"); + + static void traceDowncall(String name, Object... args) { + String traceArgs = Arrays.stream(args) + .map(Object::toString) + .collect(Collectors.joining(", ")); + System.out.printf("%s(%s)\n", name, traceArgs); + } + + static MemorySegment findOrThrow(String symbol) { + return SYMBOL_LOOKUP.find(symbol) + .orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol)); + } + + static MethodHandle upcallHandle(Class fi, String name, FunctionDescriptor fdesc) { + try { + return MethodHandles.lookup().findVirtual(fi, name, fdesc.toMethodType()); + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + static MemoryLayout align(MemoryLayout layout, long align) { + return switch (layout) { + case PaddingLayout p -> p; + case ValueLayout v -> v.withByteAlignment(align); + case GroupLayout g -> { + MemoryLayout[] alignedMembers = g.memberLayouts().stream() + .map(m -> align(m, align)).toArray(MemoryLayout[]::new); + yield g instanceof StructLayout ? + MemoryLayout.structLayout(alignedMembers) : MemoryLayout.unionLayout(alignedMembers); + } + case SequenceLayout s -> MemoryLayout.sequenceLayout(s.elementCount(), align(s.elementLayout(), align)); + }; + } + + static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup() + .or(Linker.nativeLinker().defaultLookup()); + + public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; + public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; + public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; + public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT; + public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG; + public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT; + public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE; + public static final AddressLayout C_POINTER = ValueLayout.ADDRESS + .withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE)); + public static final ValueLayout.OfLong C_LONG = ValueLayout.JAVA_LONG; + private static final int TREE_SITTER_LANGUAGE_VERSION = (int)14L; + /** + * {@snippet lang=c : + * #define TREE_SITTER_LANGUAGE_VERSION 14 + * } + */ + public static int TREE_SITTER_LANGUAGE_VERSION() { + return TREE_SITTER_LANGUAGE_VERSION; + } + private static final int TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION = (int)13L; + /** + * {@snippet lang=c : + * #define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION 13 + * } + */ + public static int TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION() { + return TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION; + } + + private static class free { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("free"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * extern void free(void *__ptr) + * } + */ + public static FunctionDescriptor free$descriptor() { + return free.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * extern void free(void *__ptr) + * } + */ + public static MethodHandle free$handle() { + return free.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * extern void free(void *__ptr) + * } + */ + public static MemorySegment free$address() { + return free.ADDR; + } + + /** + * {@snippet lang=c : + * extern void free(void *__ptr) + * } + */ + public static void free(MemorySegment __ptr) { + var mh$ = free.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("free", __ptr); + } + mh$.invokeExact(__ptr); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + private static final int TSInputEncodingUTF8 = (int)0L; + /** + * {@snippet lang=c : + * enum TSInputEncoding.TSInputEncodingUTF8 = 0 + * } + */ + public static int TSInputEncodingUTF8() { + return TSInputEncodingUTF8; + } + private static final int TSInputEncodingUTF16 = (int)1L; + /** + * {@snippet lang=c : + * enum TSInputEncoding.TSInputEncodingUTF16 = 1 + * } + */ + public static int TSInputEncodingUTF16() { + return TSInputEncodingUTF16; + } + private static final int TSSymbolTypeRegular = (int)0L; + /** + * {@snippet lang=c : + * enum TSSymbolType.TSSymbolTypeRegular = 0 + * } + */ + public static int TSSymbolTypeRegular() { + return TSSymbolTypeRegular; + } + private static final int TSSymbolTypeAnonymous = (int)1L; + /** + * {@snippet lang=c : + * enum TSSymbolType.TSSymbolTypeAnonymous = 1 + * } + */ + public static int TSSymbolTypeAnonymous() { + return TSSymbolTypeAnonymous; + } + private static final int TSSymbolTypeAuxiliary = (int)2L; + /** + * {@snippet lang=c : + * enum TSSymbolType.TSSymbolTypeAuxiliary = 2 + * } + */ + public static int TSSymbolTypeAuxiliary() { + return TSSymbolTypeAuxiliary; + } + private static final int TSLogTypeParse = (int)0L; + /** + * {@snippet lang=c : + * enum TSLogType.TSLogTypeParse = 0 + * } + */ + public static int TSLogTypeParse() { + return TSLogTypeParse; + } + private static final int TSLogTypeLex = (int)1L; + /** + * {@snippet lang=c : + * enum TSLogType.TSLogTypeLex = 1 + * } + */ + public static int TSLogTypeLex() { + return TSLogTypeLex; + } + private static final int TSQuantifierZero = (int)0L; + /** + * {@snippet lang=c : + * enum TSQuantifier.TSQuantifierZero = 0 + * } + */ + public static int TSQuantifierZero() { + return TSQuantifierZero; + } + private static final int TSQuantifierZeroOrOne = (int)1L; + /** + * {@snippet lang=c : + * enum TSQuantifier.TSQuantifierZeroOrOne = 1 + * } + */ + public static int TSQuantifierZeroOrOne() { + return TSQuantifierZeroOrOne; + } + private static final int TSQuantifierZeroOrMore = (int)2L; + /** + * {@snippet lang=c : + * enum TSQuantifier.TSQuantifierZeroOrMore = 2 + * } + */ + public static int TSQuantifierZeroOrMore() { + return TSQuantifierZeroOrMore; + } + private static final int TSQuantifierOne = (int)3L; + /** + * {@snippet lang=c : + * enum TSQuantifier.TSQuantifierOne = 3 + * } + */ + public static int TSQuantifierOne() { + return TSQuantifierOne; + } + private static final int TSQuantifierOneOrMore = (int)4L; + /** + * {@snippet lang=c : + * enum TSQuantifier.TSQuantifierOneOrMore = 4 + * } + */ + public static int TSQuantifierOneOrMore() { + return TSQuantifierOneOrMore; + } + private static final int TSQueryPredicateStepTypeDone = (int)0L; + /** + * {@snippet lang=c : + * enum TSQueryPredicateStepType.TSQueryPredicateStepTypeDone = 0 + * } + */ + public static int TSQueryPredicateStepTypeDone() { + return TSQueryPredicateStepTypeDone; + } + private static final int TSQueryPredicateStepTypeCapture = (int)1L; + /** + * {@snippet lang=c : + * enum TSQueryPredicateStepType.TSQueryPredicateStepTypeCapture = 1 + * } + */ + public static int TSQueryPredicateStepTypeCapture() { + return TSQueryPredicateStepTypeCapture; + } + private static final int TSQueryPredicateStepTypeString = (int)2L; + /** + * {@snippet lang=c : + * enum TSQueryPredicateStepType.TSQueryPredicateStepTypeString = 2 + * } + */ + public static int TSQueryPredicateStepTypeString() { + return TSQueryPredicateStepTypeString; + } + private static final int TSQueryErrorNone = (int)0L; + /** + * {@snippet lang=c : + * enum TSQueryError.TSQueryErrorNone = 0 + * } + */ + public static int TSQueryErrorNone() { + return TSQueryErrorNone; + } + private static final int TSQueryErrorSyntax = (int)1L; + /** + * {@snippet lang=c : + * enum TSQueryError.TSQueryErrorSyntax = 1 + * } + */ + public static int TSQueryErrorSyntax() { + return TSQueryErrorSyntax; + } + private static final int TSQueryErrorNodeType = (int)2L; + /** + * {@snippet lang=c : + * enum TSQueryError.TSQueryErrorNodeType = 2 + * } + */ + public static int TSQueryErrorNodeType() { + return TSQueryErrorNodeType; + } + private static final int TSQueryErrorField = (int)3L; + /** + * {@snippet lang=c : + * enum TSQueryError.TSQueryErrorField = 3 + * } + */ + public static int TSQueryErrorField() { + return TSQueryErrorField; + } + private static final int TSQueryErrorCapture = (int)4L; + /** + * {@snippet lang=c : + * enum TSQueryError.TSQueryErrorCapture = 4 + * } + */ + public static int TSQueryErrorCapture() { + return TSQueryErrorCapture; + } + private static final int TSQueryErrorStructure = (int)5L; + /** + * {@snippet lang=c : + * enum TSQueryError.TSQueryErrorStructure = 5 + * } + */ + public static int TSQueryErrorStructure() { + return TSQueryErrorStructure; + } + private static final int TSQueryErrorLanguage = (int)6L; + /** + * {@snippet lang=c : + * enum TSQueryError.TSQueryErrorLanguage = 6 + * } + */ + public static int TSQueryErrorLanguage() { + return TSQueryErrorLanguage; + } + + private static class ts_parser_new { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_new"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSParser *ts_parser_new() + * } + */ + public static FunctionDescriptor ts_parser_new$descriptor() { + return ts_parser_new.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSParser *ts_parser_new() + * } + */ + public static MethodHandle ts_parser_new$handle() { + return ts_parser_new.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSParser *ts_parser_new() + * } + */ + public static MemorySegment ts_parser_new$address() { + return ts_parser_new.ADDR; + } + + /** + * {@snippet lang=c : + * TSParser *ts_parser_new() + * } + */ + public static MemorySegment ts_parser_new() { + var mh$ = ts_parser_new.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_new"); + } + return (MemorySegment)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_delete { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_delete"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_parser_delete(TSParser *self) + * } + */ + public static FunctionDescriptor ts_parser_delete$descriptor() { + return ts_parser_delete.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_parser_delete(TSParser *self) + * } + */ + public static MethodHandle ts_parser_delete$handle() { + return ts_parser_delete.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_parser_delete(TSParser *self) + * } + */ + public static MemorySegment ts_parser_delete$address() { + return ts_parser_delete.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_parser_delete(TSParser *self) + * } + */ + public static void ts_parser_delete(MemorySegment self) { + var mh$ = ts_parser_delete.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_delete", self); + } + mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_language { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_language"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSLanguage *ts_parser_language(const TSParser *self) + * } + */ + public static FunctionDescriptor ts_parser_language$descriptor() { + return ts_parser_language.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSLanguage *ts_parser_language(const TSParser *self) + * } + */ + public static MethodHandle ts_parser_language$handle() { + return ts_parser_language.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSLanguage *ts_parser_language(const TSParser *self) + * } + */ + public static MemorySegment ts_parser_language$address() { + return ts_parser_language.ADDR; + } + + /** + * {@snippet lang=c : + * const TSLanguage *ts_parser_language(const TSParser *self) + * } + */ + public static MemorySegment ts_parser_language(MemorySegment self) { + var mh$ = ts_parser_language.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_language", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_set_language { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_set_language"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_parser_set_language(TSParser *self, const TSLanguage *language) + * } + */ + public static FunctionDescriptor ts_parser_set_language$descriptor() { + return ts_parser_set_language.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_parser_set_language(TSParser *self, const TSLanguage *language) + * } + */ + public static MethodHandle ts_parser_set_language$handle() { + return ts_parser_set_language.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_parser_set_language(TSParser *self, const TSLanguage *language) + * } + */ + public static MemorySegment ts_parser_set_language$address() { + return ts_parser_set_language.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_parser_set_language(TSParser *self, const TSLanguage *language) + * } + */ + public static boolean ts_parser_set_language(MemorySegment self, MemorySegment language) { + var mh$ = ts_parser_set_language.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_set_language", self, language); + } + return (boolean)mh$.invokeExact(self, language); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_set_included_ranges { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_set_included_ranges"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_parser_set_included_ranges(TSParser *self, const TSRange *ranges, uint32_t count) + * } + */ + public static FunctionDescriptor ts_parser_set_included_ranges$descriptor() { + return ts_parser_set_included_ranges.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_parser_set_included_ranges(TSParser *self, const TSRange *ranges, uint32_t count) + * } + */ + public static MethodHandle ts_parser_set_included_ranges$handle() { + return ts_parser_set_included_ranges.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_parser_set_included_ranges(TSParser *self, const TSRange *ranges, uint32_t count) + * } + */ + public static MemorySegment ts_parser_set_included_ranges$address() { + return ts_parser_set_included_ranges.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_parser_set_included_ranges(TSParser *self, const TSRange *ranges, uint32_t count) + * } + */ + public static boolean ts_parser_set_included_ranges(MemorySegment self, MemorySegment ranges, int count) { + var mh$ = ts_parser_set_included_ranges.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_set_included_ranges", self, ranges, count); + } + return (boolean)mh$.invokeExact(self, ranges, count); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_included_ranges { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_included_ranges"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSRange *ts_parser_included_ranges(const TSParser *self, uint32_t *count) + * } + */ + public static FunctionDescriptor ts_parser_included_ranges$descriptor() { + return ts_parser_included_ranges.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSRange *ts_parser_included_ranges(const TSParser *self, uint32_t *count) + * } + */ + public static MethodHandle ts_parser_included_ranges$handle() { + return ts_parser_included_ranges.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSRange *ts_parser_included_ranges(const TSParser *self, uint32_t *count) + * } + */ + public static MemorySegment ts_parser_included_ranges$address() { + return ts_parser_included_ranges.ADDR; + } + + /** + * {@snippet lang=c : + * const TSRange *ts_parser_included_ranges(const TSParser *self, uint32_t *count) + * } + */ + public static MemorySegment ts_parser_included_ranges(MemorySegment self, MemorySegment count) { + var mh$ = ts_parser_included_ranges.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_included_ranges", self, count); + } + return (MemorySegment)mh$.invokeExact(self, count); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_parse { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TSInput.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_parse"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSTree *ts_parser_parse(TSParser *self, const TSTree *old_tree, TSInput input) + * } + */ + public static FunctionDescriptor ts_parser_parse$descriptor() { + return ts_parser_parse.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSTree *ts_parser_parse(TSParser *self, const TSTree *old_tree, TSInput input) + * } + */ + public static MethodHandle ts_parser_parse$handle() { + return ts_parser_parse.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSTree *ts_parser_parse(TSParser *self, const TSTree *old_tree, TSInput input) + * } + */ + public static MemorySegment ts_parser_parse$address() { + return ts_parser_parse.ADDR; + } + + /** + * {@snippet lang=c : + * TSTree *ts_parser_parse(TSParser *self, const TSTree *old_tree, TSInput input) + * } + */ + public static MemorySegment ts_parser_parse(MemorySegment self, MemorySegment old_tree, MemorySegment input) { + var mh$ = ts_parser_parse.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_parse", self, old_tree, input); + } + return (MemorySegment)mh$.invokeExact(self, old_tree, input); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_parse_string { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_parse_string"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSTree *ts_parser_parse_string(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length) + * } + */ + public static FunctionDescriptor ts_parser_parse_string$descriptor() { + return ts_parser_parse_string.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSTree *ts_parser_parse_string(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length) + * } + */ + public static MethodHandle ts_parser_parse_string$handle() { + return ts_parser_parse_string.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSTree *ts_parser_parse_string(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length) + * } + */ + public static MemorySegment ts_parser_parse_string$address() { + return ts_parser_parse_string.ADDR; + } + + /** + * {@snippet lang=c : + * TSTree *ts_parser_parse_string(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length) + * } + */ + public static MemorySegment ts_parser_parse_string(MemorySegment self, MemorySegment old_tree, MemorySegment string, int length) { + var mh$ = ts_parser_parse_string.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_parse_string", self, old_tree, string, length); + } + return (MemorySegment)mh$.invokeExact(self, old_tree, string, length); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_parse_string_encoding { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_parse_string_encoding"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSTree *ts_parser_parse_string_encoding(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length, TSInputEncoding encoding) + * } + */ + public static FunctionDescriptor ts_parser_parse_string_encoding$descriptor() { + return ts_parser_parse_string_encoding.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSTree *ts_parser_parse_string_encoding(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length, TSInputEncoding encoding) + * } + */ + public static MethodHandle ts_parser_parse_string_encoding$handle() { + return ts_parser_parse_string_encoding.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSTree *ts_parser_parse_string_encoding(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length, TSInputEncoding encoding) + * } + */ + public static MemorySegment ts_parser_parse_string_encoding$address() { + return ts_parser_parse_string_encoding.ADDR; + } + + /** + * {@snippet lang=c : + * TSTree *ts_parser_parse_string_encoding(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length, TSInputEncoding encoding) + * } + */ + public static MemorySegment ts_parser_parse_string_encoding(MemorySegment self, MemorySegment old_tree, MemorySegment string, int length, int encoding) { + var mh$ = ts_parser_parse_string_encoding.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_parse_string_encoding", self, old_tree, string, length, encoding); + } + return (MemorySegment)mh$.invokeExact(self, old_tree, string, length, encoding); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_reset { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_reset"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_parser_reset(TSParser *self) + * } + */ + public static FunctionDescriptor ts_parser_reset$descriptor() { + return ts_parser_reset.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_parser_reset(TSParser *self) + * } + */ + public static MethodHandle ts_parser_reset$handle() { + return ts_parser_reset.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_parser_reset(TSParser *self) + * } + */ + public static MemorySegment ts_parser_reset$address() { + return ts_parser_reset.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_parser_reset(TSParser *self) + * } + */ + public static void ts_parser_reset(MemorySegment self) { + var mh$ = ts_parser_reset.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_reset", self); + } + mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_set_timeout_micros { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_LONG + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_set_timeout_micros"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros) + * } + */ + public static FunctionDescriptor ts_parser_set_timeout_micros$descriptor() { + return ts_parser_set_timeout_micros.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros) + * } + */ + public static MethodHandle ts_parser_set_timeout_micros$handle() { + return ts_parser_set_timeout_micros.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros) + * } + */ + public static MemorySegment ts_parser_set_timeout_micros$address() { + return ts_parser_set_timeout_micros.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros) + * } + */ + public static void ts_parser_set_timeout_micros(MemorySegment self, long timeout_micros) { + var mh$ = ts_parser_set_timeout_micros.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_set_timeout_micros", self, timeout_micros); + } + mh$.invokeExact(self, timeout_micros); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_timeout_micros { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_LONG, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_timeout_micros"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint64_t ts_parser_timeout_micros(const TSParser *self) + * } + */ + public static FunctionDescriptor ts_parser_timeout_micros$descriptor() { + return ts_parser_timeout_micros.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint64_t ts_parser_timeout_micros(const TSParser *self) + * } + */ + public static MethodHandle ts_parser_timeout_micros$handle() { + return ts_parser_timeout_micros.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint64_t ts_parser_timeout_micros(const TSParser *self) + * } + */ + public static MemorySegment ts_parser_timeout_micros$address() { + return ts_parser_timeout_micros.ADDR; + } + + /** + * {@snippet lang=c : + * uint64_t ts_parser_timeout_micros(const TSParser *self) + * } + */ + public static long ts_parser_timeout_micros(MemorySegment self) { + var mh$ = ts_parser_timeout_micros.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_timeout_micros", self); + } + return (long)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_set_cancellation_flag { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_set_cancellation_flag"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag) + * } + */ + public static FunctionDescriptor ts_parser_set_cancellation_flag$descriptor() { + return ts_parser_set_cancellation_flag.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag) + * } + */ + public static MethodHandle ts_parser_set_cancellation_flag$handle() { + return ts_parser_set_cancellation_flag.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag) + * } + */ + public static MemorySegment ts_parser_set_cancellation_flag$address() { + return ts_parser_set_cancellation_flag.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag) + * } + */ + public static void ts_parser_set_cancellation_flag(MemorySegment self, MemorySegment flag) { + var mh$ = ts_parser_set_cancellation_flag.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_set_cancellation_flag", self, flag); + } + mh$.invokeExact(self, flag); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_cancellation_flag { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_cancellation_flag"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const size_t *ts_parser_cancellation_flag(const TSParser *self) + * } + */ + public static FunctionDescriptor ts_parser_cancellation_flag$descriptor() { + return ts_parser_cancellation_flag.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const size_t *ts_parser_cancellation_flag(const TSParser *self) + * } + */ + public static MethodHandle ts_parser_cancellation_flag$handle() { + return ts_parser_cancellation_flag.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const size_t *ts_parser_cancellation_flag(const TSParser *self) + * } + */ + public static MemorySegment ts_parser_cancellation_flag$address() { + return ts_parser_cancellation_flag.ADDR; + } + + /** + * {@snippet lang=c : + * const size_t *ts_parser_cancellation_flag(const TSParser *self) + * } + */ + public static MemorySegment ts_parser_cancellation_flag(MemorySegment self) { + var mh$ = ts_parser_cancellation_flag.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_cancellation_flag", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_set_logger { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TSLogger.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_set_logger"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_parser_set_logger(TSParser *self, TSLogger logger) + * } + */ + public static FunctionDescriptor ts_parser_set_logger$descriptor() { + return ts_parser_set_logger.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_parser_set_logger(TSParser *self, TSLogger logger) + * } + */ + public static MethodHandle ts_parser_set_logger$handle() { + return ts_parser_set_logger.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_parser_set_logger(TSParser *self, TSLogger logger) + * } + */ + public static MemorySegment ts_parser_set_logger$address() { + return ts_parser_set_logger.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_parser_set_logger(TSParser *self, TSLogger logger) + * } + */ + public static void ts_parser_set_logger(MemorySegment self, MemorySegment logger) { + var mh$ = ts_parser_set_logger.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_set_logger", self, logger); + } + mh$.invokeExact(self, logger); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_logger { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSLogger.layout(), + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_logger"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSLogger ts_parser_logger(const TSParser *self) + * } + */ + public static FunctionDescriptor ts_parser_logger$descriptor() { + return ts_parser_logger.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSLogger ts_parser_logger(const TSParser *self) + * } + */ + public static MethodHandle ts_parser_logger$handle() { + return ts_parser_logger.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSLogger ts_parser_logger(const TSParser *self) + * } + */ + public static MemorySegment ts_parser_logger$address() { + return ts_parser_logger.ADDR; + } + + /** + * {@snippet lang=c : + * TSLogger ts_parser_logger(const TSParser *self) + * } + */ + public static MemorySegment ts_parser_logger(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_parser_logger.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_logger", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_parser_print_dot_graphs { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_parser_print_dot_graphs"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_parser_print_dot_graphs(TSParser *self, int fd) + * } + */ + public static FunctionDescriptor ts_parser_print_dot_graphs$descriptor() { + return ts_parser_print_dot_graphs.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_parser_print_dot_graphs(TSParser *self, int fd) + * } + */ + public static MethodHandle ts_parser_print_dot_graphs$handle() { + return ts_parser_print_dot_graphs.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_parser_print_dot_graphs(TSParser *self, int fd) + * } + */ + public static MemorySegment ts_parser_print_dot_graphs$address() { + return ts_parser_print_dot_graphs.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_parser_print_dot_graphs(TSParser *self, int fd) + * } + */ + public static void ts_parser_print_dot_graphs(MemorySegment self, int fd) { + var mh$ = ts_parser_print_dot_graphs.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_parser_print_dot_graphs", self, fd); + } + mh$.invokeExact(self, fd); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_copy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_copy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSTree *ts_tree_copy(const TSTree *self) + * } + */ + public static FunctionDescriptor ts_tree_copy$descriptor() { + return ts_tree_copy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSTree *ts_tree_copy(const TSTree *self) + * } + */ + public static MethodHandle ts_tree_copy$handle() { + return ts_tree_copy.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSTree *ts_tree_copy(const TSTree *self) + * } + */ + public static MemorySegment ts_tree_copy$address() { + return ts_tree_copy.ADDR; + } + + /** + * {@snippet lang=c : + * TSTree *ts_tree_copy(const TSTree *self) + * } + */ + public static MemorySegment ts_tree_copy(MemorySegment self) { + var mh$ = ts_tree_copy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_copy", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_delete { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_delete"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_tree_delete(TSTree *self) + * } + */ + public static FunctionDescriptor ts_tree_delete$descriptor() { + return ts_tree_delete.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_tree_delete(TSTree *self) + * } + */ + public static MethodHandle ts_tree_delete$handle() { + return ts_tree_delete.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_tree_delete(TSTree *self) + * } + */ + public static MemorySegment ts_tree_delete$address() { + return ts_tree_delete.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_tree_delete(TSTree *self) + * } + */ + public static void ts_tree_delete(MemorySegment self) { + var mh$ = ts_tree_delete.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_delete", self); + } + mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_root_node { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_root_node"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_tree_root_node(const TSTree *self) + * } + */ + public static FunctionDescriptor ts_tree_root_node$descriptor() { + return ts_tree_root_node.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_tree_root_node(const TSTree *self) + * } + */ + public static MethodHandle ts_tree_root_node$handle() { + return ts_tree_root_node.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_tree_root_node(const TSTree *self) + * } + */ + public static MemorySegment ts_tree_root_node$address() { + return ts_tree_root_node.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_tree_root_node(const TSTree *self) + * } + */ + public static MemorySegment ts_tree_root_node(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_tree_root_node.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_root_node", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_root_node_with_offset { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TSPoint.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_root_node_with_offset"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_tree_root_node_with_offset(const TSTree *self, uint32_t offset_bytes, TSPoint offset_extent) + * } + */ + public static FunctionDescriptor ts_tree_root_node_with_offset$descriptor() { + return ts_tree_root_node_with_offset.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_tree_root_node_with_offset(const TSTree *self, uint32_t offset_bytes, TSPoint offset_extent) + * } + */ + public static MethodHandle ts_tree_root_node_with_offset$handle() { + return ts_tree_root_node_with_offset.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_tree_root_node_with_offset(const TSTree *self, uint32_t offset_bytes, TSPoint offset_extent) + * } + */ + public static MemorySegment ts_tree_root_node_with_offset$address() { + return ts_tree_root_node_with_offset.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_tree_root_node_with_offset(const TSTree *self, uint32_t offset_bytes, TSPoint offset_extent) + * } + */ + public static MemorySegment ts_tree_root_node_with_offset(SegmentAllocator allocator, MemorySegment self, int offset_bytes, MemorySegment offset_extent) { + var mh$ = ts_tree_root_node_with_offset.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_root_node_with_offset", allocator, self, offset_bytes, offset_extent); + } + return (MemorySegment)mh$.invokeExact(allocator, self, offset_bytes, offset_extent); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_language { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_language"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSLanguage *ts_tree_language(const TSTree *self) + * } + */ + public static FunctionDescriptor ts_tree_language$descriptor() { + return ts_tree_language.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSLanguage *ts_tree_language(const TSTree *self) + * } + */ + public static MethodHandle ts_tree_language$handle() { + return ts_tree_language.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSLanguage *ts_tree_language(const TSTree *self) + * } + */ + public static MemorySegment ts_tree_language$address() { + return ts_tree_language.ADDR; + } + + /** + * {@snippet lang=c : + * const TSLanguage *ts_tree_language(const TSTree *self) + * } + */ + public static MemorySegment ts_tree_language(MemorySegment self) { + var mh$ = ts_tree_language.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_language", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_included_ranges { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_included_ranges"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length) + * } + */ + public static FunctionDescriptor ts_tree_included_ranges$descriptor() { + return ts_tree_included_ranges.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length) + * } + */ + public static MethodHandle ts_tree_included_ranges$handle() { + return ts_tree_included_ranges.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length) + * } + */ + public static MemorySegment ts_tree_included_ranges$address() { + return ts_tree_included_ranges.ADDR; + } + + /** + * {@snippet lang=c : + * TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length) + * } + */ + public static MemorySegment ts_tree_included_ranges(MemorySegment self, MemorySegment length) { + var mh$ = ts_tree_included_ranges.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_included_ranges", self, length); + } + return (MemorySegment)mh$.invokeExact(self, length); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_edit { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_edit"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_tree_edit(TSTree *self, const TSInputEdit *edit) + * } + */ + public static FunctionDescriptor ts_tree_edit$descriptor() { + return ts_tree_edit.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_tree_edit(TSTree *self, const TSInputEdit *edit) + * } + */ + public static MethodHandle ts_tree_edit$handle() { + return ts_tree_edit.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_tree_edit(TSTree *self, const TSInputEdit *edit) + * } + */ + public static MemorySegment ts_tree_edit$address() { + return ts_tree_edit.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_tree_edit(TSTree *self, const TSInputEdit *edit) + * } + */ + public static void ts_tree_edit(MemorySegment self, MemorySegment edit) { + var mh$ = ts_tree_edit.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_edit", self, edit); + } + mh$.invokeExact(self, edit); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_get_changed_ranges { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_get_changed_ranges"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSRange *ts_tree_get_changed_ranges(const TSTree *old_tree, const TSTree *new_tree, uint32_t *length) + * } + */ + public static FunctionDescriptor ts_tree_get_changed_ranges$descriptor() { + return ts_tree_get_changed_ranges.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSRange *ts_tree_get_changed_ranges(const TSTree *old_tree, const TSTree *new_tree, uint32_t *length) + * } + */ + public static MethodHandle ts_tree_get_changed_ranges$handle() { + return ts_tree_get_changed_ranges.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSRange *ts_tree_get_changed_ranges(const TSTree *old_tree, const TSTree *new_tree, uint32_t *length) + * } + */ + public static MemorySegment ts_tree_get_changed_ranges$address() { + return ts_tree_get_changed_ranges.ADDR; + } + + /** + * {@snippet lang=c : + * TSRange *ts_tree_get_changed_ranges(const TSTree *old_tree, const TSTree *new_tree, uint32_t *length) + * } + */ + public static MemorySegment ts_tree_get_changed_ranges(MemorySegment old_tree, MemorySegment new_tree, MemorySegment length) { + var mh$ = ts_tree_get_changed_ranges.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_get_changed_ranges", old_tree, new_tree, length); + } + return (MemorySegment)mh$.invokeExact(old_tree, new_tree, length); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_print_dot_graph { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_print_dot_graph"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor) + * } + */ + public static FunctionDescriptor ts_tree_print_dot_graph$descriptor() { + return ts_tree_print_dot_graph.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor) + * } + */ + public static MethodHandle ts_tree_print_dot_graph$handle() { + return ts_tree_print_dot_graph.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor) + * } + */ + public static MemorySegment ts_tree_print_dot_graph$address() { + return ts_tree_print_dot_graph.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor) + * } + */ + public static void ts_tree_print_dot_graph(MemorySegment self, int file_descriptor) { + var mh$ = ts_tree_print_dot_graph.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_print_dot_graph", self, file_descriptor); + } + mh$.invokeExact(self, file_descriptor); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_type { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_type"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_node_type(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_type$descriptor() { + return ts_node_type.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_node_type(TSNode self) + * } + */ + public static MethodHandle ts_node_type$handle() { + return ts_node_type.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_node_type(TSNode self) + * } + */ + public static MemorySegment ts_node_type$address() { + return ts_node_type.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_node_type(TSNode self) + * } + */ + public static MemorySegment ts_node_type(MemorySegment self) { + var mh$ = ts_node_type.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_type", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_symbol { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_symbol"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSSymbol ts_node_symbol(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_symbol$descriptor() { + return ts_node_symbol.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSSymbol ts_node_symbol(TSNode self) + * } + */ + public static MethodHandle ts_node_symbol$handle() { + return ts_node_symbol.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSSymbol ts_node_symbol(TSNode self) + * } + */ + public static MemorySegment ts_node_symbol$address() { + return ts_node_symbol.ADDR; + } + + /** + * {@snippet lang=c : + * TSSymbol ts_node_symbol(TSNode self) + * } + */ + public static short ts_node_symbol(MemorySegment self) { + var mh$ = ts_node_symbol.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_symbol", self); + } + return (short)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_language { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_language"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSLanguage *ts_node_language(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_language$descriptor() { + return ts_node_language.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSLanguage *ts_node_language(TSNode self) + * } + */ + public static MethodHandle ts_node_language$handle() { + return ts_node_language.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSLanguage *ts_node_language(TSNode self) + * } + */ + public static MemorySegment ts_node_language$address() { + return ts_node_language.ADDR; + } + + /** + * {@snippet lang=c : + * const TSLanguage *ts_node_language(TSNode self) + * } + */ + public static MemorySegment ts_node_language(MemorySegment self) { + var mh$ = ts_node_language.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_language", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_grammar_type { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_grammar_type"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_node_grammar_type(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_grammar_type$descriptor() { + return ts_node_grammar_type.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_node_grammar_type(TSNode self) + * } + */ + public static MethodHandle ts_node_grammar_type$handle() { + return ts_node_grammar_type.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_node_grammar_type(TSNode self) + * } + */ + public static MemorySegment ts_node_grammar_type$address() { + return ts_node_grammar_type.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_node_grammar_type(TSNode self) + * } + */ + public static MemorySegment ts_node_grammar_type(MemorySegment self) { + var mh$ = ts_node_grammar_type.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_grammar_type", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_grammar_symbol { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_grammar_symbol"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSSymbol ts_node_grammar_symbol(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_grammar_symbol$descriptor() { + return ts_node_grammar_symbol.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSSymbol ts_node_grammar_symbol(TSNode self) + * } + */ + public static MethodHandle ts_node_grammar_symbol$handle() { + return ts_node_grammar_symbol.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSSymbol ts_node_grammar_symbol(TSNode self) + * } + */ + public static MemorySegment ts_node_grammar_symbol$address() { + return ts_node_grammar_symbol.ADDR; + } + + /** + * {@snippet lang=c : + * TSSymbol ts_node_grammar_symbol(TSNode self) + * } + */ + public static short ts_node_grammar_symbol(MemorySegment self) { + var mh$ = ts_node_grammar_symbol.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_grammar_symbol", self); + } + return (short)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_start_byte { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_start_byte"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_node_start_byte(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_start_byte$descriptor() { + return ts_node_start_byte.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_node_start_byte(TSNode self) + * } + */ + public static MethodHandle ts_node_start_byte$handle() { + return ts_node_start_byte.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_node_start_byte(TSNode self) + * } + */ + public static MemorySegment ts_node_start_byte$address() { + return ts_node_start_byte.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_node_start_byte(TSNode self) + * } + */ + public static int ts_node_start_byte(MemorySegment self) { + var mh$ = ts_node_start_byte.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_start_byte", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_start_point { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSPoint.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_start_point"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSPoint ts_node_start_point(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_start_point$descriptor() { + return ts_node_start_point.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSPoint ts_node_start_point(TSNode self) + * } + */ + public static MethodHandle ts_node_start_point$handle() { + return ts_node_start_point.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSPoint ts_node_start_point(TSNode self) + * } + */ + public static MemorySegment ts_node_start_point$address() { + return ts_node_start_point.ADDR; + } + + /** + * {@snippet lang=c : + * TSPoint ts_node_start_point(TSNode self) + * } + */ + public static MemorySegment ts_node_start_point(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_node_start_point.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_start_point", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_end_byte { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_end_byte"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_node_end_byte(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_end_byte$descriptor() { + return ts_node_end_byte.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_node_end_byte(TSNode self) + * } + */ + public static MethodHandle ts_node_end_byte$handle() { + return ts_node_end_byte.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_node_end_byte(TSNode self) + * } + */ + public static MemorySegment ts_node_end_byte$address() { + return ts_node_end_byte.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_node_end_byte(TSNode self) + * } + */ + public static int ts_node_end_byte(MemorySegment self) { + var mh$ = ts_node_end_byte.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_end_byte", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_end_point { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSPoint.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_end_point"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSPoint ts_node_end_point(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_end_point$descriptor() { + return ts_node_end_point.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSPoint ts_node_end_point(TSNode self) + * } + */ + public static MethodHandle ts_node_end_point$handle() { + return ts_node_end_point.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSPoint ts_node_end_point(TSNode self) + * } + */ + public static MemorySegment ts_node_end_point$address() { + return ts_node_end_point.ADDR; + } + + /** + * {@snippet lang=c : + * TSPoint ts_node_end_point(TSNode self) + * } + */ + public static MemorySegment ts_node_end_point(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_node_end_point.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_end_point", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_string { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_string"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * char *ts_node_string(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_string$descriptor() { + return ts_node_string.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * char *ts_node_string(TSNode self) + * } + */ + public static MethodHandle ts_node_string$handle() { + return ts_node_string.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * char *ts_node_string(TSNode self) + * } + */ + public static MemorySegment ts_node_string$address() { + return ts_node_string.ADDR; + } + + /** + * {@snippet lang=c : + * char *ts_node_string(TSNode self) + * } + */ + public static MemorySegment ts_node_string(MemorySegment self) { + var mh$ = ts_node_string.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_string", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_is_null { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_is_null"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_node_is_null(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_is_null$descriptor() { + return ts_node_is_null.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_node_is_null(TSNode self) + * } + */ + public static MethodHandle ts_node_is_null$handle() { + return ts_node_is_null.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_node_is_null(TSNode self) + * } + */ + public static MemorySegment ts_node_is_null$address() { + return ts_node_is_null.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_node_is_null(TSNode self) + * } + */ + public static boolean ts_node_is_null(MemorySegment self) { + var mh$ = ts_node_is_null.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_is_null", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_is_named { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_is_named"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_node_is_named(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_is_named$descriptor() { + return ts_node_is_named.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_node_is_named(TSNode self) + * } + */ + public static MethodHandle ts_node_is_named$handle() { + return ts_node_is_named.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_node_is_named(TSNode self) + * } + */ + public static MemorySegment ts_node_is_named$address() { + return ts_node_is_named.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_node_is_named(TSNode self) + * } + */ + public static boolean ts_node_is_named(MemorySegment self) { + var mh$ = ts_node_is_named.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_is_named", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_is_missing { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_is_missing"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_node_is_missing(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_is_missing$descriptor() { + return ts_node_is_missing.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_node_is_missing(TSNode self) + * } + */ + public static MethodHandle ts_node_is_missing$handle() { + return ts_node_is_missing.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_node_is_missing(TSNode self) + * } + */ + public static MemorySegment ts_node_is_missing$address() { + return ts_node_is_missing.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_node_is_missing(TSNode self) + * } + */ + public static boolean ts_node_is_missing(MemorySegment self) { + var mh$ = ts_node_is_missing.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_is_missing", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_is_extra { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_is_extra"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_node_is_extra(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_is_extra$descriptor() { + return ts_node_is_extra.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_node_is_extra(TSNode self) + * } + */ + public static MethodHandle ts_node_is_extra$handle() { + return ts_node_is_extra.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_node_is_extra(TSNode self) + * } + */ + public static MemorySegment ts_node_is_extra$address() { + return ts_node_is_extra.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_node_is_extra(TSNode self) + * } + */ + public static boolean ts_node_is_extra(MemorySegment self) { + var mh$ = ts_node_is_extra.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_is_extra", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_has_changes { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_has_changes"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_node_has_changes(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_has_changes$descriptor() { + return ts_node_has_changes.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_node_has_changes(TSNode self) + * } + */ + public static MethodHandle ts_node_has_changes$handle() { + return ts_node_has_changes.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_node_has_changes(TSNode self) + * } + */ + public static MemorySegment ts_node_has_changes$address() { + return ts_node_has_changes.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_node_has_changes(TSNode self) + * } + */ + public static boolean ts_node_has_changes(MemorySegment self) { + var mh$ = ts_node_has_changes.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_has_changes", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_has_error { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_has_error"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_node_has_error(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_has_error$descriptor() { + return ts_node_has_error.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_node_has_error(TSNode self) + * } + */ + public static MethodHandle ts_node_has_error$handle() { + return ts_node_has_error.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_node_has_error(TSNode self) + * } + */ + public static MemorySegment ts_node_has_error$address() { + return ts_node_has_error.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_node_has_error(TSNode self) + * } + */ + public static boolean ts_node_has_error(MemorySegment self) { + var mh$ = ts_node_has_error.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_has_error", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_is_error { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_is_error"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_node_is_error(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_is_error$descriptor() { + return ts_node_is_error.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_node_is_error(TSNode self) + * } + */ + public static MethodHandle ts_node_is_error$handle() { + return ts_node_is_error.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_node_is_error(TSNode self) + * } + */ + public static MemorySegment ts_node_is_error$address() { + return ts_node_is_error.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_node_is_error(TSNode self) + * } + */ + public static boolean ts_node_is_error(MemorySegment self) { + var mh$ = ts_node_is_error.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_is_error", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_parse_state { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_parse_state"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSStateId ts_node_parse_state(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_parse_state$descriptor() { + return ts_node_parse_state.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSStateId ts_node_parse_state(TSNode self) + * } + */ + public static MethodHandle ts_node_parse_state$handle() { + return ts_node_parse_state.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSStateId ts_node_parse_state(TSNode self) + * } + */ + public static MemorySegment ts_node_parse_state$address() { + return ts_node_parse_state.ADDR; + } + + /** + * {@snippet lang=c : + * TSStateId ts_node_parse_state(TSNode self) + * } + */ + public static short ts_node_parse_state(MemorySegment self) { + var mh$ = ts_node_parse_state.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_parse_state", self); + } + return (short)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_next_parse_state { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_next_parse_state"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSStateId ts_node_next_parse_state(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_next_parse_state$descriptor() { + return ts_node_next_parse_state.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSStateId ts_node_next_parse_state(TSNode self) + * } + */ + public static MethodHandle ts_node_next_parse_state$handle() { + return ts_node_next_parse_state.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSStateId ts_node_next_parse_state(TSNode self) + * } + */ + public static MemorySegment ts_node_next_parse_state$address() { + return ts_node_next_parse_state.ADDR; + } + + /** + * {@snippet lang=c : + * TSStateId ts_node_next_parse_state(TSNode self) + * } + */ + public static short ts_node_next_parse_state(MemorySegment self) { + var mh$ = ts_node_next_parse_state.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_next_parse_state", self); + } + return (short)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_parent { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_parent"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_parent(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_parent$descriptor() { + return ts_node_parent.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_parent(TSNode self) + * } + */ + public static MethodHandle ts_node_parent$handle() { + return ts_node_parent.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_parent(TSNode self) + * } + */ + public static MemorySegment ts_node_parent$address() { + return ts_node_parent.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_parent(TSNode self) + * } + */ + public static MemorySegment ts_node_parent(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_node_parent.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_parent", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_child_containing_descendant { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_child_containing_descendant"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant) + * } + */ + public static FunctionDescriptor ts_node_child_containing_descendant$descriptor() { + return ts_node_child_containing_descendant.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant) + * } + */ + public static MethodHandle ts_node_child_containing_descendant$handle() { + return ts_node_child_containing_descendant.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant) + * } + */ + public static MemorySegment ts_node_child_containing_descendant$address() { + return ts_node_child_containing_descendant.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant) + * } + */ + public static MemorySegment ts_node_child_containing_descendant(SegmentAllocator allocator, MemorySegment self, MemorySegment descendant) { + var mh$ = ts_node_child_containing_descendant.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_child_containing_descendant", allocator, self, descendant); + } + return (MemorySegment)mh$.invokeExact(allocator, self, descendant); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_child { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_child"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_child(TSNode self, uint32_t child_index) + * } + */ + public static FunctionDescriptor ts_node_child$descriptor() { + return ts_node_child.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_child(TSNode self, uint32_t child_index) + * } + */ + public static MethodHandle ts_node_child$handle() { + return ts_node_child.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_child(TSNode self, uint32_t child_index) + * } + */ + public static MemorySegment ts_node_child$address() { + return ts_node_child.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_child(TSNode self, uint32_t child_index) + * } + */ + public static MemorySegment ts_node_child(SegmentAllocator allocator, MemorySegment self, int child_index) { + var mh$ = ts_node_child.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_child", allocator, self, child_index); + } + return (MemorySegment)mh$.invokeExact(allocator, self, child_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_field_name_for_child { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TSNode.layout(), + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_field_name_for_child"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index) + * } + */ + public static FunctionDescriptor ts_node_field_name_for_child$descriptor() { + return ts_node_field_name_for_child.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index) + * } + */ + public static MethodHandle ts_node_field_name_for_child$handle() { + return ts_node_field_name_for_child.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index) + * } + */ + public static MemorySegment ts_node_field_name_for_child$address() { + return ts_node_field_name_for_child.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index) + * } + */ + public static MemorySegment ts_node_field_name_for_child(MemorySegment self, int child_index) { + var mh$ = ts_node_field_name_for_child.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_field_name_for_child", self, child_index); + } + return (MemorySegment)mh$.invokeExact(self, child_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_child_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_child_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_node_child_count(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_child_count$descriptor() { + return ts_node_child_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_node_child_count(TSNode self) + * } + */ + public static MethodHandle ts_node_child_count$handle() { + return ts_node_child_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_node_child_count(TSNode self) + * } + */ + public static MemorySegment ts_node_child_count$address() { + return ts_node_child_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_node_child_count(TSNode self) + * } + */ + public static int ts_node_child_count(MemorySegment self) { + var mh$ = ts_node_child_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_child_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_named_child { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_named_child"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_named_child(TSNode self, uint32_t child_index) + * } + */ + public static FunctionDescriptor ts_node_named_child$descriptor() { + return ts_node_named_child.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_named_child(TSNode self, uint32_t child_index) + * } + */ + public static MethodHandle ts_node_named_child$handle() { + return ts_node_named_child.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_named_child(TSNode self, uint32_t child_index) + * } + */ + public static MemorySegment ts_node_named_child$address() { + return ts_node_named_child.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_named_child(TSNode self, uint32_t child_index) + * } + */ + public static MemorySegment ts_node_named_child(SegmentAllocator allocator, MemorySegment self, int child_index) { + var mh$ = ts_node_named_child.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_named_child", allocator, self, child_index); + } + return (MemorySegment)mh$.invokeExact(allocator, self, child_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_named_child_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_named_child_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_node_named_child_count(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_named_child_count$descriptor() { + return ts_node_named_child_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_node_named_child_count(TSNode self) + * } + */ + public static MethodHandle ts_node_named_child_count$handle() { + return ts_node_named_child_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_node_named_child_count(TSNode self) + * } + */ + public static MemorySegment ts_node_named_child_count$address() { + return ts_node_named_child_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_node_named_child_count(TSNode self) + * } + */ + public static int ts_node_named_child_count(MemorySegment self) { + var mh$ = ts_node_named_child_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_named_child_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_child_by_field_name { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_child_by_field_name"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_child_by_field_name(TSNode self, const char *name, uint32_t name_length) + * } + */ + public static FunctionDescriptor ts_node_child_by_field_name$descriptor() { + return ts_node_child_by_field_name.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_child_by_field_name(TSNode self, const char *name, uint32_t name_length) + * } + */ + public static MethodHandle ts_node_child_by_field_name$handle() { + return ts_node_child_by_field_name.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_child_by_field_name(TSNode self, const char *name, uint32_t name_length) + * } + */ + public static MemorySegment ts_node_child_by_field_name$address() { + return ts_node_child_by_field_name.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_child_by_field_name(TSNode self, const char *name, uint32_t name_length) + * } + */ + public static MemorySegment ts_node_child_by_field_name(SegmentAllocator allocator, MemorySegment self, MemorySegment name, int name_length) { + var mh$ = ts_node_child_by_field_name.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_child_by_field_name", allocator, self, name, name_length); + } + return (MemorySegment)mh$.invokeExact(allocator, self, name, name_length); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_child_by_field_id { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TreeSitter.C_SHORT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_child_by_field_id"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id) + * } + */ + public static FunctionDescriptor ts_node_child_by_field_id$descriptor() { + return ts_node_child_by_field_id.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id) + * } + */ + public static MethodHandle ts_node_child_by_field_id$handle() { + return ts_node_child_by_field_id.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id) + * } + */ + public static MemorySegment ts_node_child_by_field_id$address() { + return ts_node_child_by_field_id.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id) + * } + */ + public static MemorySegment ts_node_child_by_field_id(SegmentAllocator allocator, MemorySegment self, short field_id) { + var mh$ = ts_node_child_by_field_id.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_child_by_field_id", allocator, self, field_id); + } + return (MemorySegment)mh$.invokeExact(allocator, self, field_id); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_next_sibling { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_next_sibling"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_next_sibling(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_next_sibling$descriptor() { + return ts_node_next_sibling.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_next_sibling(TSNode self) + * } + */ + public static MethodHandle ts_node_next_sibling$handle() { + return ts_node_next_sibling.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_next_sibling(TSNode self) + * } + */ + public static MemorySegment ts_node_next_sibling$address() { + return ts_node_next_sibling.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_next_sibling(TSNode self) + * } + */ + public static MemorySegment ts_node_next_sibling(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_node_next_sibling.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_next_sibling", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_prev_sibling { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_prev_sibling"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_prev_sibling(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_prev_sibling$descriptor() { + return ts_node_prev_sibling.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_prev_sibling(TSNode self) + * } + */ + public static MethodHandle ts_node_prev_sibling$handle() { + return ts_node_prev_sibling.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_prev_sibling(TSNode self) + * } + */ + public static MemorySegment ts_node_prev_sibling$address() { + return ts_node_prev_sibling.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_prev_sibling(TSNode self) + * } + */ + public static MemorySegment ts_node_prev_sibling(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_node_prev_sibling.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_prev_sibling", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_next_named_sibling { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_next_named_sibling"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_next_named_sibling(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_next_named_sibling$descriptor() { + return ts_node_next_named_sibling.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_next_named_sibling(TSNode self) + * } + */ + public static MethodHandle ts_node_next_named_sibling$handle() { + return ts_node_next_named_sibling.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_next_named_sibling(TSNode self) + * } + */ + public static MemorySegment ts_node_next_named_sibling$address() { + return ts_node_next_named_sibling.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_next_named_sibling(TSNode self) + * } + */ + public static MemorySegment ts_node_next_named_sibling(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_node_next_named_sibling.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_next_named_sibling", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_prev_named_sibling { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_prev_named_sibling"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_prev_named_sibling(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_prev_named_sibling$descriptor() { + return ts_node_prev_named_sibling.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_prev_named_sibling(TSNode self) + * } + */ + public static MethodHandle ts_node_prev_named_sibling$handle() { + return ts_node_prev_named_sibling.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_prev_named_sibling(TSNode self) + * } + */ + public static MemorySegment ts_node_prev_named_sibling$address() { + return ts_node_prev_named_sibling.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_prev_named_sibling(TSNode self) + * } + */ + public static MemorySegment ts_node_prev_named_sibling(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_node_prev_named_sibling.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_prev_named_sibling", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_first_child_for_byte { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_first_child_for_byte"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte) + * } + */ + public static FunctionDescriptor ts_node_first_child_for_byte$descriptor() { + return ts_node_first_child_for_byte.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte) + * } + */ + public static MethodHandle ts_node_first_child_for_byte$handle() { + return ts_node_first_child_for_byte.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte) + * } + */ + public static MemorySegment ts_node_first_child_for_byte$address() { + return ts_node_first_child_for_byte.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte) + * } + */ + public static MemorySegment ts_node_first_child_for_byte(SegmentAllocator allocator, MemorySegment self, int byte_) { + var mh$ = ts_node_first_child_for_byte.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_first_child_for_byte", allocator, self, byte_); + } + return (MemorySegment)mh$.invokeExact(allocator, self, byte_); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_first_named_child_for_byte { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_first_named_child_for_byte"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte) + * } + */ + public static FunctionDescriptor ts_node_first_named_child_for_byte$descriptor() { + return ts_node_first_named_child_for_byte.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte) + * } + */ + public static MethodHandle ts_node_first_named_child_for_byte$handle() { + return ts_node_first_named_child_for_byte.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte) + * } + */ + public static MemorySegment ts_node_first_named_child_for_byte$address() { + return ts_node_first_named_child_for_byte.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte) + * } + */ + public static MemorySegment ts_node_first_named_child_for_byte(SegmentAllocator allocator, MemorySegment self, int byte_) { + var mh$ = ts_node_first_named_child_for_byte.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_first_named_child_for_byte", allocator, self, byte_); + } + return (MemorySegment)mh$.invokeExact(allocator, self, byte_); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_descendant_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_descendant_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_node_descendant_count(TSNode self) + * } + */ + public static FunctionDescriptor ts_node_descendant_count$descriptor() { + return ts_node_descendant_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_node_descendant_count(TSNode self) + * } + */ + public static MethodHandle ts_node_descendant_count$handle() { + return ts_node_descendant_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_node_descendant_count(TSNode self) + * } + */ + public static MemorySegment ts_node_descendant_count$address() { + return ts_node_descendant_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_node_descendant_count(TSNode self) + * } + */ + public static int ts_node_descendant_count(MemorySegment self) { + var mh$ = ts_node_descendant_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_descendant_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_descendant_for_byte_range { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TreeSitter.C_INT, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_descendant_for_byte_range"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end) + * } + */ + public static FunctionDescriptor ts_node_descendant_for_byte_range$descriptor() { + return ts_node_descendant_for_byte_range.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end) + * } + */ + public static MethodHandle ts_node_descendant_for_byte_range$handle() { + return ts_node_descendant_for_byte_range.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end) + * } + */ + public static MemorySegment ts_node_descendant_for_byte_range$address() { + return ts_node_descendant_for_byte_range.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end) + * } + */ + public static MemorySegment ts_node_descendant_for_byte_range(SegmentAllocator allocator, MemorySegment self, int start, int end) { + var mh$ = ts_node_descendant_for_byte_range.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_descendant_for_byte_range", allocator, self, start, end); + } + return (MemorySegment)mh$.invokeExact(allocator, self, start, end); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_descendant_for_point_range { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TSPoint.layout(), + TSPoint.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_descendant_for_point_range"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end) + * } + */ + public static FunctionDescriptor ts_node_descendant_for_point_range$descriptor() { + return ts_node_descendant_for_point_range.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end) + * } + */ + public static MethodHandle ts_node_descendant_for_point_range$handle() { + return ts_node_descendant_for_point_range.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end) + * } + */ + public static MemorySegment ts_node_descendant_for_point_range$address() { + return ts_node_descendant_for_point_range.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end) + * } + */ + public static MemorySegment ts_node_descendant_for_point_range(SegmentAllocator allocator, MemorySegment self, MemorySegment start, MemorySegment end) { + var mh$ = ts_node_descendant_for_point_range.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_descendant_for_point_range", allocator, self, start, end); + } + return (MemorySegment)mh$.invokeExact(allocator, self, start, end); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_named_descendant_for_byte_range { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TreeSitter.C_INT, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_named_descendant_for_byte_range"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end) + * } + */ + public static FunctionDescriptor ts_node_named_descendant_for_byte_range$descriptor() { + return ts_node_named_descendant_for_byte_range.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end) + * } + */ + public static MethodHandle ts_node_named_descendant_for_byte_range$handle() { + return ts_node_named_descendant_for_byte_range.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end) + * } + */ + public static MemorySegment ts_node_named_descendant_for_byte_range$address() { + return ts_node_named_descendant_for_byte_range.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end) + * } + */ + public static MemorySegment ts_node_named_descendant_for_byte_range(SegmentAllocator allocator, MemorySegment self, int start, int end) { + var mh$ = ts_node_named_descendant_for_byte_range.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_named_descendant_for_byte_range", allocator, self, start, end); + } + return (MemorySegment)mh$.invokeExact(allocator, self, start, end); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_named_descendant_for_point_range { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TSNode.layout(), + TSPoint.layout(), + TSPoint.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_named_descendant_for_point_range"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end) + * } + */ + public static FunctionDescriptor ts_node_named_descendant_for_point_range$descriptor() { + return ts_node_named_descendant_for_point_range.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end) + * } + */ + public static MethodHandle ts_node_named_descendant_for_point_range$handle() { + return ts_node_named_descendant_for_point_range.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end) + * } + */ + public static MemorySegment ts_node_named_descendant_for_point_range$address() { + return ts_node_named_descendant_for_point_range.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end) + * } + */ + public static MemorySegment ts_node_named_descendant_for_point_range(SegmentAllocator allocator, MemorySegment self, MemorySegment start, MemorySegment end) { + var mh$ = ts_node_named_descendant_for_point_range.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_named_descendant_for_point_range", allocator, self, start, end); + } + return (MemorySegment)mh$.invokeExact(allocator, self, start, end); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_edit { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_edit"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_node_edit(TSNode *self, const TSInputEdit *edit) + * } + */ + public static FunctionDescriptor ts_node_edit$descriptor() { + return ts_node_edit.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_node_edit(TSNode *self, const TSInputEdit *edit) + * } + */ + public static MethodHandle ts_node_edit$handle() { + return ts_node_edit.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_node_edit(TSNode *self, const TSInputEdit *edit) + * } + */ + public static MemorySegment ts_node_edit$address() { + return ts_node_edit.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_node_edit(TSNode *self, const TSInputEdit *edit) + * } + */ + public static void ts_node_edit(MemorySegment self, MemorySegment edit) { + var mh$ = ts_node_edit.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_edit", self, edit); + } + mh$.invokeExact(self, edit); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_node_eq { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TSNode.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_node_eq"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_node_eq(TSNode self, TSNode other) + * } + */ + public static FunctionDescriptor ts_node_eq$descriptor() { + return ts_node_eq.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_node_eq(TSNode self, TSNode other) + * } + */ + public static MethodHandle ts_node_eq$handle() { + return ts_node_eq.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_node_eq(TSNode self, TSNode other) + * } + */ + public static MemorySegment ts_node_eq$address() { + return ts_node_eq.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_node_eq(TSNode self, TSNode other) + * } + */ + public static boolean ts_node_eq(MemorySegment self, MemorySegment other) { + var mh$ = ts_node_eq.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_node_eq", self, other); + } + return (boolean)mh$.invokeExact(self, other); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_new { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSTreeCursor.layout(), + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_new"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSTreeCursor ts_tree_cursor_new(TSNode node) + * } + */ + public static FunctionDescriptor ts_tree_cursor_new$descriptor() { + return ts_tree_cursor_new.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSTreeCursor ts_tree_cursor_new(TSNode node) + * } + */ + public static MethodHandle ts_tree_cursor_new$handle() { + return ts_tree_cursor_new.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSTreeCursor ts_tree_cursor_new(TSNode node) + * } + */ + public static MemorySegment ts_tree_cursor_new$address() { + return ts_tree_cursor_new.ADDR; + } + + /** + * {@snippet lang=c : + * TSTreeCursor ts_tree_cursor_new(TSNode node) + * } + */ + public static MemorySegment ts_tree_cursor_new(SegmentAllocator allocator, MemorySegment node) { + var mh$ = ts_tree_cursor_new.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_new", allocator, node); + } + return (MemorySegment)mh$.invokeExact(allocator, node); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_delete { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_delete"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_tree_cursor_delete(TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_delete$descriptor() { + return ts_tree_cursor_delete.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_tree_cursor_delete(TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_delete$handle() { + return ts_tree_cursor_delete.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_tree_cursor_delete(TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_delete$address() { + return ts_tree_cursor_delete.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_tree_cursor_delete(TSTreeCursor *self) + * } + */ + public static void ts_tree_cursor_delete(MemorySegment self) { + var mh$ = ts_tree_cursor_delete.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_delete", self); + } + mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_reset { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_reset"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node) + * } + */ + public static FunctionDescriptor ts_tree_cursor_reset$descriptor() { + return ts_tree_cursor_reset.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node) + * } + */ + public static MethodHandle ts_tree_cursor_reset$handle() { + return ts_tree_cursor_reset.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node) + * } + */ + public static MemorySegment ts_tree_cursor_reset$address() { + return ts_tree_cursor_reset.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node) + * } + */ + public static void ts_tree_cursor_reset(MemorySegment self, MemorySegment node) { + var mh$ = ts_tree_cursor_reset.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_reset", self, node); + } + mh$.invokeExact(self, node); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_reset_to { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_reset_to"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src) + * } + */ + public static FunctionDescriptor ts_tree_cursor_reset_to$descriptor() { + return ts_tree_cursor_reset_to.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src) + * } + */ + public static MethodHandle ts_tree_cursor_reset_to$handle() { + return ts_tree_cursor_reset_to.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src) + * } + */ + public static MemorySegment ts_tree_cursor_reset_to$address() { + return ts_tree_cursor_reset_to.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src) + * } + */ + public static void ts_tree_cursor_reset_to(MemorySegment dst, MemorySegment src) { + var mh$ = ts_tree_cursor_reset_to.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_reset_to", dst, src); + } + mh$.invokeExact(dst, src); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_current_node { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSNode.layout(), + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_current_node"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSNode ts_tree_cursor_current_node(const TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_current_node$descriptor() { + return ts_tree_cursor_current_node.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSNode ts_tree_cursor_current_node(const TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_current_node$handle() { + return ts_tree_cursor_current_node.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSNode ts_tree_cursor_current_node(const TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_current_node$address() { + return ts_tree_cursor_current_node.ADDR; + } + + /** + * {@snippet lang=c : + * TSNode ts_tree_cursor_current_node(const TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_current_node(SegmentAllocator allocator, MemorySegment self) { + var mh$ = ts_tree_cursor_current_node.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_current_node", allocator, self); + } + return (MemorySegment)mh$.invokeExact(allocator, self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_current_field_name { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_current_field_name"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_current_field_name$descriptor() { + return ts_tree_cursor_current_field_name.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_current_field_name$handle() { + return ts_tree_cursor_current_field_name.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_current_field_name$address() { + return ts_tree_cursor_current_field_name.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_current_field_name(MemorySegment self) { + var mh$ = ts_tree_cursor_current_field_name.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_current_field_name", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_current_field_id { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_current_field_id"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_current_field_id$descriptor() { + return ts_tree_cursor_current_field_id.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_current_field_id$handle() { + return ts_tree_cursor_current_field_id.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_current_field_id$address() { + return ts_tree_cursor_current_field_id.ADDR; + } + + /** + * {@snippet lang=c : + * TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self) + * } + */ + public static short ts_tree_cursor_current_field_id(MemorySegment self) { + var mh$ = ts_tree_cursor_current_field_id.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_current_field_id", self); + } + return (short)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_goto_parent { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_goto_parent"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_parent(TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_goto_parent$descriptor() { + return ts_tree_cursor_goto_parent.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_parent(TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_goto_parent$handle() { + return ts_tree_cursor_goto_parent.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_parent(TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_goto_parent$address() { + return ts_tree_cursor_goto_parent.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_parent(TSTreeCursor *self) + * } + */ + public static boolean ts_tree_cursor_goto_parent(MemorySegment self) { + var mh$ = ts_tree_cursor_goto_parent.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_goto_parent", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_goto_next_sibling { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_goto_next_sibling"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_goto_next_sibling$descriptor() { + return ts_tree_cursor_goto_next_sibling.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_goto_next_sibling$handle() { + return ts_tree_cursor_goto_next_sibling.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_goto_next_sibling$address() { + return ts_tree_cursor_goto_next_sibling.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) + * } + */ + public static boolean ts_tree_cursor_goto_next_sibling(MemorySegment self) { + var mh$ = ts_tree_cursor_goto_next_sibling.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_goto_next_sibling", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_goto_previous_sibling { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_goto_previous_sibling"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_goto_previous_sibling$descriptor() { + return ts_tree_cursor_goto_previous_sibling.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_goto_previous_sibling$handle() { + return ts_tree_cursor_goto_previous_sibling.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_goto_previous_sibling$address() { + return ts_tree_cursor_goto_previous_sibling.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self) + * } + */ + public static boolean ts_tree_cursor_goto_previous_sibling(MemorySegment self) { + var mh$ = ts_tree_cursor_goto_previous_sibling.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_goto_previous_sibling", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_goto_first_child { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_goto_first_child"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_goto_first_child$descriptor() { + return ts_tree_cursor_goto_first_child.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_goto_first_child$handle() { + return ts_tree_cursor_goto_first_child.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_goto_first_child$address() { + return ts_tree_cursor_goto_first_child.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) + * } + */ + public static boolean ts_tree_cursor_goto_first_child(MemorySegment self) { + var mh$ = ts_tree_cursor_goto_first_child.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_goto_first_child", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_goto_last_child { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_goto_last_child"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_last_child(TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_goto_last_child$descriptor() { + return ts_tree_cursor_goto_last_child.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_last_child(TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_goto_last_child$handle() { + return ts_tree_cursor_goto_last_child.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_last_child(TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_goto_last_child$address() { + return ts_tree_cursor_goto_last_child.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_tree_cursor_goto_last_child(TSTreeCursor *self) + * } + */ + public static boolean ts_tree_cursor_goto_last_child(MemorySegment self) { + var mh$ = ts_tree_cursor_goto_last_child.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_goto_last_child", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_goto_descendant { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_goto_descendant"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index) + * } + */ + public static FunctionDescriptor ts_tree_cursor_goto_descendant$descriptor() { + return ts_tree_cursor_goto_descendant.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index) + * } + */ + public static MethodHandle ts_tree_cursor_goto_descendant$handle() { + return ts_tree_cursor_goto_descendant.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index) + * } + */ + public static MemorySegment ts_tree_cursor_goto_descendant$address() { + return ts_tree_cursor_goto_descendant.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index) + * } + */ + public static void ts_tree_cursor_goto_descendant(MemorySegment self, int goal_descendant_index) { + var mh$ = ts_tree_cursor_goto_descendant.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_goto_descendant", self, goal_descendant_index); + } + mh$.invokeExact(self, goal_descendant_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_current_descendant_index { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_current_descendant_index"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_current_descendant_index$descriptor() { + return ts_tree_cursor_current_descendant_index.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_current_descendant_index$handle() { + return ts_tree_cursor_current_descendant_index.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_current_descendant_index$address() { + return ts_tree_cursor_current_descendant_index.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self) + * } + */ + public static int ts_tree_cursor_current_descendant_index(MemorySegment self) { + var mh$ = ts_tree_cursor_current_descendant_index.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_current_descendant_index", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_current_depth { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_current_depth"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self) + * } + */ + public static FunctionDescriptor ts_tree_cursor_current_depth$descriptor() { + return ts_tree_cursor_current_depth.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self) + * } + */ + public static MethodHandle ts_tree_cursor_current_depth$handle() { + return ts_tree_cursor_current_depth.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self) + * } + */ + public static MemorySegment ts_tree_cursor_current_depth$address() { + return ts_tree_cursor_current_depth.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self) + * } + */ + public static int ts_tree_cursor_current_depth(MemorySegment self) { + var mh$ = ts_tree_cursor_current_depth.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_current_depth", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_goto_first_child_for_byte { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_LONG, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_goto_first_child_for_byte"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) + * } + */ + public static FunctionDescriptor ts_tree_cursor_goto_first_child_for_byte$descriptor() { + return ts_tree_cursor_goto_first_child_for_byte.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) + * } + */ + public static MethodHandle ts_tree_cursor_goto_first_child_for_byte$handle() { + return ts_tree_cursor_goto_first_child_for_byte.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) + * } + */ + public static MemorySegment ts_tree_cursor_goto_first_child_for_byte$address() { + return ts_tree_cursor_goto_first_child_for_byte.ADDR; + } + + /** + * {@snippet lang=c : + * int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) + * } + */ + public static long ts_tree_cursor_goto_first_child_for_byte(MemorySegment self, int goal_byte) { + var mh$ = ts_tree_cursor_goto_first_child_for_byte.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_goto_first_child_for_byte", self, goal_byte); + } + return (long)mh$.invokeExact(self, goal_byte); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_goto_first_child_for_point { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_LONG, + TreeSitter.C_POINTER, + TSPoint.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_goto_first_child_for_point"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point) + * } + */ + public static FunctionDescriptor ts_tree_cursor_goto_first_child_for_point$descriptor() { + return ts_tree_cursor_goto_first_child_for_point.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point) + * } + */ + public static MethodHandle ts_tree_cursor_goto_first_child_for_point$handle() { + return ts_tree_cursor_goto_first_child_for_point.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point) + * } + */ + public static MemorySegment ts_tree_cursor_goto_first_child_for_point$address() { + return ts_tree_cursor_goto_first_child_for_point.ADDR; + } + + /** + * {@snippet lang=c : + * int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point) + * } + */ + public static long ts_tree_cursor_goto_first_child_for_point(MemorySegment self, MemorySegment goal_point) { + var mh$ = ts_tree_cursor_goto_first_child_for_point.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_goto_first_child_for_point", self, goal_point); + } + return (long)mh$.invokeExact(self, goal_point); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_tree_cursor_copy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TSTreeCursor.layout(), + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_tree_cursor_copy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor) + * } + */ + public static FunctionDescriptor ts_tree_cursor_copy$descriptor() { + return ts_tree_cursor_copy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor) + * } + */ + public static MethodHandle ts_tree_cursor_copy$handle() { + return ts_tree_cursor_copy.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor) + * } + */ + public static MemorySegment ts_tree_cursor_copy$address() { + return ts_tree_cursor_copy.ADDR; + } + + /** + * {@snippet lang=c : + * TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor) + * } + */ + public static MemorySegment ts_tree_cursor_copy(SegmentAllocator allocator, MemorySegment cursor) { + var mh$ = ts_tree_cursor_copy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_tree_cursor_copy", allocator, cursor); + } + return (MemorySegment)mh$.invokeExact(allocator, cursor); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_new { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_new"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSQuery *ts_query_new(const TSLanguage *language, const char *source, uint32_t source_len, uint32_t *error_offset, TSQueryError *error_type) + * } + */ + public static FunctionDescriptor ts_query_new$descriptor() { + return ts_query_new.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSQuery *ts_query_new(const TSLanguage *language, const char *source, uint32_t source_len, uint32_t *error_offset, TSQueryError *error_type) + * } + */ + public static MethodHandle ts_query_new$handle() { + return ts_query_new.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSQuery *ts_query_new(const TSLanguage *language, const char *source, uint32_t source_len, uint32_t *error_offset, TSQueryError *error_type) + * } + */ + public static MemorySegment ts_query_new$address() { + return ts_query_new.ADDR; + } + + /** + * {@snippet lang=c : + * TSQuery *ts_query_new(const TSLanguage *language, const char *source, uint32_t source_len, uint32_t *error_offset, TSQueryError *error_type) + * } + */ + public static MemorySegment ts_query_new(MemorySegment language, MemorySegment source, int source_len, MemorySegment error_offset, MemorySegment error_type) { + var mh$ = ts_query_new.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_new", language, source, source_len, error_offset, error_type); + } + return (MemorySegment)mh$.invokeExact(language, source, source_len, error_offset, error_type); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_delete { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_delete"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_delete(TSQuery *self) + * } + */ + public static FunctionDescriptor ts_query_delete$descriptor() { + return ts_query_delete.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_delete(TSQuery *self) + * } + */ + public static MethodHandle ts_query_delete$handle() { + return ts_query_delete.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_delete(TSQuery *self) + * } + */ + public static MemorySegment ts_query_delete$address() { + return ts_query_delete.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_delete(TSQuery *self) + * } + */ + public static void ts_query_delete(MemorySegment self) { + var mh$ = ts_query_delete.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_delete", self); + } + mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_pattern_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_pattern_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_query_pattern_count(const TSQuery *self) + * } + */ + public static FunctionDescriptor ts_query_pattern_count$descriptor() { + return ts_query_pattern_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_query_pattern_count(const TSQuery *self) + * } + */ + public static MethodHandle ts_query_pattern_count$handle() { + return ts_query_pattern_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_query_pattern_count(const TSQuery *self) + * } + */ + public static MemorySegment ts_query_pattern_count$address() { + return ts_query_pattern_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_query_pattern_count(const TSQuery *self) + * } + */ + public static int ts_query_pattern_count(MemorySegment self) { + var mh$ = ts_query_pattern_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_pattern_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_capture_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_capture_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_query_capture_count(const TSQuery *self) + * } + */ + public static FunctionDescriptor ts_query_capture_count$descriptor() { + return ts_query_capture_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_query_capture_count(const TSQuery *self) + * } + */ + public static MethodHandle ts_query_capture_count$handle() { + return ts_query_capture_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_query_capture_count(const TSQuery *self) + * } + */ + public static MemorySegment ts_query_capture_count$address() { + return ts_query_capture_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_query_capture_count(const TSQuery *self) + * } + */ + public static int ts_query_capture_count(MemorySegment self) { + var mh$ = ts_query_capture_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_capture_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_string_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_string_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_query_string_count(const TSQuery *self) + * } + */ + public static FunctionDescriptor ts_query_string_count$descriptor() { + return ts_query_string_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_query_string_count(const TSQuery *self) + * } + */ + public static MethodHandle ts_query_string_count$handle() { + return ts_query_string_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_query_string_count(const TSQuery *self) + * } + */ + public static MemorySegment ts_query_string_count$address() { + return ts_query_string_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_query_string_count(const TSQuery *self) + * } + */ + public static int ts_query_string_count(MemorySegment self) { + var mh$ = ts_query_string_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_string_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_start_byte_for_pattern { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_start_byte_for_pattern"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static FunctionDescriptor ts_query_start_byte_for_pattern$descriptor() { + return ts_query_start_byte_for_pattern.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static MethodHandle ts_query_start_byte_for_pattern$handle() { + return ts_query_start_byte_for_pattern.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static MemorySegment ts_query_start_byte_for_pattern$address() { + return ts_query_start_byte_for_pattern.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static int ts_query_start_byte_for_pattern(MemorySegment self, int pattern_index) { + var mh$ = ts_query_start_byte_for_pattern.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_start_byte_for_pattern", self, pattern_index); + } + return (int)mh$.invokeExact(self, pattern_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_end_byte_for_pattern { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_end_byte_for_pattern"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static FunctionDescriptor ts_query_end_byte_for_pattern$descriptor() { + return ts_query_end_byte_for_pattern.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static MethodHandle ts_query_end_byte_for_pattern$handle() { + return ts_query_end_byte_for_pattern.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static MemorySegment ts_query_end_byte_for_pattern$address() { + return ts_query_end_byte_for_pattern.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static int ts_query_end_byte_for_pattern(MemorySegment self, int pattern_index) { + var mh$ = ts_query_end_byte_for_pattern.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_end_byte_for_pattern", self, pattern_index); + } + return (int)mh$.invokeExact(self, pattern_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_predicates_for_pattern { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_predicates_for_pattern"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSQueryPredicateStep *ts_query_predicates_for_pattern(const TSQuery *self, uint32_t pattern_index, uint32_t *step_count) + * } + */ + public static FunctionDescriptor ts_query_predicates_for_pattern$descriptor() { + return ts_query_predicates_for_pattern.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSQueryPredicateStep *ts_query_predicates_for_pattern(const TSQuery *self, uint32_t pattern_index, uint32_t *step_count) + * } + */ + public static MethodHandle ts_query_predicates_for_pattern$handle() { + return ts_query_predicates_for_pattern.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSQueryPredicateStep *ts_query_predicates_for_pattern(const TSQuery *self, uint32_t pattern_index, uint32_t *step_count) + * } + */ + public static MemorySegment ts_query_predicates_for_pattern$address() { + return ts_query_predicates_for_pattern.ADDR; + } + + /** + * {@snippet lang=c : + * const TSQueryPredicateStep *ts_query_predicates_for_pattern(const TSQuery *self, uint32_t pattern_index, uint32_t *step_count) + * } + */ + public static MemorySegment ts_query_predicates_for_pattern(MemorySegment self, int pattern_index, MemorySegment step_count) { + var mh$ = ts_query_predicates_for_pattern.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_predicates_for_pattern", self, pattern_index, step_count); + } + return (MemorySegment)mh$.invokeExact(self, pattern_index, step_count); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_is_pattern_rooted { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_is_pattern_rooted"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static FunctionDescriptor ts_query_is_pattern_rooted$descriptor() { + return ts_query_is_pattern_rooted.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static MethodHandle ts_query_is_pattern_rooted$handle() { + return ts_query_is_pattern_rooted.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static MemorySegment ts_query_is_pattern_rooted$address() { + return ts_query_is_pattern_rooted.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static boolean ts_query_is_pattern_rooted(MemorySegment self, int pattern_index) { + var mh$ = ts_query_is_pattern_rooted.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_is_pattern_rooted", self, pattern_index); + } + return (boolean)mh$.invokeExact(self, pattern_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_is_pattern_non_local { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_is_pattern_non_local"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static FunctionDescriptor ts_query_is_pattern_non_local$descriptor() { + return ts_query_is_pattern_non_local.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static MethodHandle ts_query_is_pattern_non_local$handle() { + return ts_query_is_pattern_non_local.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static MemorySegment ts_query_is_pattern_non_local$address() { + return ts_query_is_pattern_non_local.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index) + * } + */ + public static boolean ts_query_is_pattern_non_local(MemorySegment self, int pattern_index) { + var mh$ = ts_query_is_pattern_non_local.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_is_pattern_non_local", self, pattern_index); + } + return (boolean)mh$.invokeExact(self, pattern_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_is_pattern_guaranteed_at_step { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_is_pattern_guaranteed_at_step"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset) + * } + */ + public static FunctionDescriptor ts_query_is_pattern_guaranteed_at_step$descriptor() { + return ts_query_is_pattern_guaranteed_at_step.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset) + * } + */ + public static MethodHandle ts_query_is_pattern_guaranteed_at_step$handle() { + return ts_query_is_pattern_guaranteed_at_step.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset) + * } + */ + public static MemorySegment ts_query_is_pattern_guaranteed_at_step$address() { + return ts_query_is_pattern_guaranteed_at_step.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset) + * } + */ + public static boolean ts_query_is_pattern_guaranteed_at_step(MemorySegment self, int byte_offset) { + var mh$ = ts_query_is_pattern_guaranteed_at_step.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_is_pattern_guaranteed_at_step", self, byte_offset); + } + return (boolean)mh$.invokeExact(self, byte_offset); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_capture_name_for_id { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_capture_name_for_id"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_query_capture_name_for_id(const TSQuery *self, uint32_t index, uint32_t *length) + * } + */ + public static FunctionDescriptor ts_query_capture_name_for_id$descriptor() { + return ts_query_capture_name_for_id.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_query_capture_name_for_id(const TSQuery *self, uint32_t index, uint32_t *length) + * } + */ + public static MethodHandle ts_query_capture_name_for_id$handle() { + return ts_query_capture_name_for_id.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_query_capture_name_for_id(const TSQuery *self, uint32_t index, uint32_t *length) + * } + */ + public static MemorySegment ts_query_capture_name_for_id$address() { + return ts_query_capture_name_for_id.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_query_capture_name_for_id(const TSQuery *self, uint32_t index, uint32_t *length) + * } + */ + public static MemorySegment ts_query_capture_name_for_id(MemorySegment self, int index, MemorySegment length) { + var mh$ = ts_query_capture_name_for_id.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_capture_name_for_id", self, index, length); + } + return (MemorySegment)mh$.invokeExact(self, index, length); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_capture_quantifier_for_id { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_capture_quantifier_for_id"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSQuantifier ts_query_capture_quantifier_for_id(const TSQuery *self, uint32_t pattern_index, uint32_t capture_index) + * } + */ + public static FunctionDescriptor ts_query_capture_quantifier_for_id$descriptor() { + return ts_query_capture_quantifier_for_id.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSQuantifier ts_query_capture_quantifier_for_id(const TSQuery *self, uint32_t pattern_index, uint32_t capture_index) + * } + */ + public static MethodHandle ts_query_capture_quantifier_for_id$handle() { + return ts_query_capture_quantifier_for_id.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSQuantifier ts_query_capture_quantifier_for_id(const TSQuery *self, uint32_t pattern_index, uint32_t capture_index) + * } + */ + public static MemorySegment ts_query_capture_quantifier_for_id$address() { + return ts_query_capture_quantifier_for_id.ADDR; + } + + /** + * {@snippet lang=c : + * TSQuantifier ts_query_capture_quantifier_for_id(const TSQuery *self, uint32_t pattern_index, uint32_t capture_index) + * } + */ + public static int ts_query_capture_quantifier_for_id(MemorySegment self, int pattern_index, int capture_index) { + var mh$ = ts_query_capture_quantifier_for_id.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_capture_quantifier_for_id", self, pattern_index, capture_index); + } + return (int)mh$.invokeExact(self, pattern_index, capture_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_string_value_for_id { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_string_value_for_id"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_query_string_value_for_id(const TSQuery *self, uint32_t index, uint32_t *length) + * } + */ + public static FunctionDescriptor ts_query_string_value_for_id$descriptor() { + return ts_query_string_value_for_id.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_query_string_value_for_id(const TSQuery *self, uint32_t index, uint32_t *length) + * } + */ + public static MethodHandle ts_query_string_value_for_id$handle() { + return ts_query_string_value_for_id.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_query_string_value_for_id(const TSQuery *self, uint32_t index, uint32_t *length) + * } + */ + public static MemorySegment ts_query_string_value_for_id$address() { + return ts_query_string_value_for_id.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_query_string_value_for_id(const TSQuery *self, uint32_t index, uint32_t *length) + * } + */ + public static MemorySegment ts_query_string_value_for_id(MemorySegment self, int index, MemorySegment length) { + var mh$ = ts_query_string_value_for_id.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_string_value_for_id", self, index, length); + } + return (MemorySegment)mh$.invokeExact(self, index, length); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_disable_capture { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_disable_capture"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length) + * } + */ + public static FunctionDescriptor ts_query_disable_capture$descriptor() { + return ts_query_disable_capture.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length) + * } + */ + public static MethodHandle ts_query_disable_capture$handle() { + return ts_query_disable_capture.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length) + * } + */ + public static MemorySegment ts_query_disable_capture$address() { + return ts_query_disable_capture.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length) + * } + */ + public static void ts_query_disable_capture(MemorySegment self, MemorySegment name, int length) { + var mh$ = ts_query_disable_capture.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_disable_capture", self, name, length); + } + mh$.invokeExact(self, name, length); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_disable_pattern { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_disable_pattern"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index) + * } + */ + public static FunctionDescriptor ts_query_disable_pattern$descriptor() { + return ts_query_disable_pattern.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index) + * } + */ + public static MethodHandle ts_query_disable_pattern$handle() { + return ts_query_disable_pattern.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index) + * } + */ + public static MemorySegment ts_query_disable_pattern$address() { + return ts_query_disable_pattern.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index) + * } + */ + public static void ts_query_disable_pattern(MemorySegment self, int pattern_index) { + var mh$ = ts_query_disable_pattern.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_disable_pattern", self, pattern_index); + } + mh$.invokeExact(self, pattern_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_new { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_new"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSQueryCursor *ts_query_cursor_new() + * } + */ + public static FunctionDescriptor ts_query_cursor_new$descriptor() { + return ts_query_cursor_new.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSQueryCursor *ts_query_cursor_new() + * } + */ + public static MethodHandle ts_query_cursor_new$handle() { + return ts_query_cursor_new.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSQueryCursor *ts_query_cursor_new() + * } + */ + public static MemorySegment ts_query_cursor_new$address() { + return ts_query_cursor_new.ADDR; + } + + /** + * {@snippet lang=c : + * TSQueryCursor *ts_query_cursor_new() + * } + */ + public static MemorySegment ts_query_cursor_new() { + var mh$ = ts_query_cursor_new.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_new"); + } + return (MemorySegment)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_delete { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_delete"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_cursor_delete(TSQueryCursor *self) + * } + */ + public static FunctionDescriptor ts_query_cursor_delete$descriptor() { + return ts_query_cursor_delete.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_cursor_delete(TSQueryCursor *self) + * } + */ + public static MethodHandle ts_query_cursor_delete$handle() { + return ts_query_cursor_delete.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_cursor_delete(TSQueryCursor *self) + * } + */ + public static MemorySegment ts_query_cursor_delete$address() { + return ts_query_cursor_delete.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_cursor_delete(TSQueryCursor *self) + * } + */ + public static void ts_query_cursor_delete(MemorySegment self) { + var mh$ = ts_query_cursor_delete.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_delete", self); + } + mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_exec { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TSNode.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_exec"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node) + * } + */ + public static FunctionDescriptor ts_query_cursor_exec$descriptor() { + return ts_query_cursor_exec.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node) + * } + */ + public static MethodHandle ts_query_cursor_exec$handle() { + return ts_query_cursor_exec.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node) + * } + */ + public static MemorySegment ts_query_cursor_exec$address() { + return ts_query_cursor_exec.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node) + * } + */ + public static void ts_query_cursor_exec(MemorySegment self, MemorySegment query, MemorySegment node) { + var mh$ = ts_query_cursor_exec.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_exec", self, query, node); + } + mh$.invokeExact(self, query, node); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_did_exceed_match_limit { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_did_exceed_match_limit"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self) + * } + */ + public static FunctionDescriptor ts_query_cursor_did_exceed_match_limit$descriptor() { + return ts_query_cursor_did_exceed_match_limit.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self) + * } + */ + public static MethodHandle ts_query_cursor_did_exceed_match_limit$handle() { + return ts_query_cursor_did_exceed_match_limit.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self) + * } + */ + public static MemorySegment ts_query_cursor_did_exceed_match_limit$address() { + return ts_query_cursor_did_exceed_match_limit.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self) + * } + */ + public static boolean ts_query_cursor_did_exceed_match_limit(MemorySegment self) { + var mh$ = ts_query_cursor_did_exceed_match_limit.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_did_exceed_match_limit", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_match_limit { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_match_limit"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self) + * } + */ + public static FunctionDescriptor ts_query_cursor_match_limit$descriptor() { + return ts_query_cursor_match_limit.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self) + * } + */ + public static MethodHandle ts_query_cursor_match_limit$handle() { + return ts_query_cursor_match_limit.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self) + * } + */ + public static MemorySegment ts_query_cursor_match_limit$address() { + return ts_query_cursor_match_limit.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self) + * } + */ + public static int ts_query_cursor_match_limit(MemorySegment self) { + var mh$ = ts_query_cursor_match_limit.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_match_limit", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_set_match_limit { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_set_match_limit"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit) + * } + */ + public static FunctionDescriptor ts_query_cursor_set_match_limit$descriptor() { + return ts_query_cursor_set_match_limit.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit) + * } + */ + public static MethodHandle ts_query_cursor_set_match_limit$handle() { + return ts_query_cursor_set_match_limit.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit) + * } + */ + public static MemorySegment ts_query_cursor_set_match_limit$address() { + return ts_query_cursor_set_match_limit.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit) + * } + */ + public static void ts_query_cursor_set_match_limit(MemorySegment self, int limit) { + var mh$ = ts_query_cursor_set_match_limit.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_set_match_limit", self, limit); + } + mh$.invokeExact(self, limit); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_set_byte_range { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_set_byte_range"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte) + * } + */ + public static FunctionDescriptor ts_query_cursor_set_byte_range$descriptor() { + return ts_query_cursor_set_byte_range.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte) + * } + */ + public static MethodHandle ts_query_cursor_set_byte_range$handle() { + return ts_query_cursor_set_byte_range.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte) + * } + */ + public static MemorySegment ts_query_cursor_set_byte_range$address() { + return ts_query_cursor_set_byte_range.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte) + * } + */ + public static void ts_query_cursor_set_byte_range(MemorySegment self, int start_byte, int end_byte) { + var mh$ = ts_query_cursor_set_byte_range.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_set_byte_range", self, start_byte, end_byte); + } + mh$.invokeExact(self, start_byte, end_byte); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_set_point_range { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TSPoint.layout(), + TSPoint.layout() + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_set_point_range"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point) + * } + */ + public static FunctionDescriptor ts_query_cursor_set_point_range$descriptor() { + return ts_query_cursor_set_point_range.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point) + * } + */ + public static MethodHandle ts_query_cursor_set_point_range$handle() { + return ts_query_cursor_set_point_range.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point) + * } + */ + public static MemorySegment ts_query_cursor_set_point_range$address() { + return ts_query_cursor_set_point_range.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point) + * } + */ + public static void ts_query_cursor_set_point_range(MemorySegment self, MemorySegment start_point, MemorySegment end_point) { + var mh$ = ts_query_cursor_set_point_range.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_set_point_range", self, start_point, end_point); + } + mh$.invokeExact(self, start_point, end_point); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_next_match { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_next_match"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match) + * } + */ + public static FunctionDescriptor ts_query_cursor_next_match$descriptor() { + return ts_query_cursor_next_match.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match) + * } + */ + public static MethodHandle ts_query_cursor_next_match$handle() { + return ts_query_cursor_next_match.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match) + * } + */ + public static MemorySegment ts_query_cursor_next_match$address() { + return ts_query_cursor_next_match.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match) + * } + */ + public static boolean ts_query_cursor_next_match(MemorySegment self, MemorySegment match) { + var mh$ = ts_query_cursor_next_match.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_next_match", self, match); + } + return (boolean)mh$.invokeExact(self, match); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_remove_match { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_remove_match"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id) + * } + */ + public static FunctionDescriptor ts_query_cursor_remove_match$descriptor() { + return ts_query_cursor_remove_match.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id) + * } + */ + public static MethodHandle ts_query_cursor_remove_match$handle() { + return ts_query_cursor_remove_match.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id) + * } + */ + public static MemorySegment ts_query_cursor_remove_match$address() { + return ts_query_cursor_remove_match.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id) + * } + */ + public static void ts_query_cursor_remove_match(MemorySegment self, int match_id) { + var mh$ = ts_query_cursor_remove_match.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_remove_match", self, match_id); + } + mh$.invokeExact(self, match_id); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_next_capture { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_next_capture"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_query_cursor_next_capture(TSQueryCursor *self, TSQueryMatch *match, uint32_t *capture_index) + * } + */ + public static FunctionDescriptor ts_query_cursor_next_capture$descriptor() { + return ts_query_cursor_next_capture.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_query_cursor_next_capture(TSQueryCursor *self, TSQueryMatch *match, uint32_t *capture_index) + * } + */ + public static MethodHandle ts_query_cursor_next_capture$handle() { + return ts_query_cursor_next_capture.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_query_cursor_next_capture(TSQueryCursor *self, TSQueryMatch *match, uint32_t *capture_index) + * } + */ + public static MemorySegment ts_query_cursor_next_capture$address() { + return ts_query_cursor_next_capture.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_query_cursor_next_capture(TSQueryCursor *self, TSQueryMatch *match, uint32_t *capture_index) + * } + */ + public static boolean ts_query_cursor_next_capture(MemorySegment self, MemorySegment match, MemorySegment capture_index) { + var mh$ = ts_query_cursor_next_capture.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_next_capture", self, match, capture_index); + } + return (boolean)mh$.invokeExact(self, match, capture_index); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_query_cursor_set_max_start_depth { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_query_cursor_set_max_start_depth"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth) + * } + */ + public static FunctionDescriptor ts_query_cursor_set_max_start_depth$descriptor() { + return ts_query_cursor_set_max_start_depth.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth) + * } + */ + public static MethodHandle ts_query_cursor_set_max_start_depth$handle() { + return ts_query_cursor_set_max_start_depth.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth) + * } + */ + public static MemorySegment ts_query_cursor_set_max_start_depth$address() { + return ts_query_cursor_set_max_start_depth.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth) + * } + */ + public static void ts_query_cursor_set_max_start_depth(MemorySegment self, int max_start_depth) { + var mh$ = ts_query_cursor_set_max_start_depth.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_query_cursor_set_max_start_depth", self, max_start_depth); + } + mh$.invokeExact(self, max_start_depth); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_copy { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_copy"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSLanguage *ts_language_copy(const TSLanguage *self) + * } + */ + public static FunctionDescriptor ts_language_copy$descriptor() { + return ts_language_copy.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSLanguage *ts_language_copy(const TSLanguage *self) + * } + */ + public static MethodHandle ts_language_copy$handle() { + return ts_language_copy.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSLanguage *ts_language_copy(const TSLanguage *self) + * } + */ + public static MemorySegment ts_language_copy$address() { + return ts_language_copy.ADDR; + } + + /** + * {@snippet lang=c : + * const TSLanguage *ts_language_copy(const TSLanguage *self) + * } + */ + public static MemorySegment ts_language_copy(MemorySegment self) { + var mh$ = ts_language_copy.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_copy", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_delete { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_delete"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_language_delete(const TSLanguage *self) + * } + */ + public static FunctionDescriptor ts_language_delete$descriptor() { + return ts_language_delete.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_language_delete(const TSLanguage *self) + * } + */ + public static MethodHandle ts_language_delete$handle() { + return ts_language_delete.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_language_delete(const TSLanguage *self) + * } + */ + public static MemorySegment ts_language_delete$address() { + return ts_language_delete.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_language_delete(const TSLanguage *self) + * } + */ + public static void ts_language_delete(MemorySegment self) { + var mh$ = ts_language_delete.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_delete", self); + } + mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_symbol_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_symbol_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_language_symbol_count(const TSLanguage *self) + * } + */ + public static FunctionDescriptor ts_language_symbol_count$descriptor() { + return ts_language_symbol_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_language_symbol_count(const TSLanguage *self) + * } + */ + public static MethodHandle ts_language_symbol_count$handle() { + return ts_language_symbol_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_language_symbol_count(const TSLanguage *self) + * } + */ + public static MemorySegment ts_language_symbol_count$address() { + return ts_language_symbol_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_language_symbol_count(const TSLanguage *self) + * } + */ + public static int ts_language_symbol_count(MemorySegment self) { + var mh$ = ts_language_symbol_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_symbol_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_state_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_state_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_language_state_count(const TSLanguage *self) + * } + */ + public static FunctionDescriptor ts_language_state_count$descriptor() { + return ts_language_state_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_language_state_count(const TSLanguage *self) + * } + */ + public static MethodHandle ts_language_state_count$handle() { + return ts_language_state_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_language_state_count(const TSLanguage *self) + * } + */ + public static MemorySegment ts_language_state_count$address() { + return ts_language_state_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_language_state_count(const TSLanguage *self) + * } + */ + public static int ts_language_state_count(MemorySegment self) { + var mh$ = ts_language_state_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_state_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_symbol_name { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_SHORT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_symbol_name"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol) + * } + */ + public static FunctionDescriptor ts_language_symbol_name$descriptor() { + return ts_language_symbol_name.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol) + * } + */ + public static MethodHandle ts_language_symbol_name$handle() { + return ts_language_symbol_name.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol) + * } + */ + public static MemorySegment ts_language_symbol_name$address() { + return ts_language_symbol_name.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol) + * } + */ + public static MemorySegment ts_language_symbol_name(MemorySegment self, short symbol) { + var mh$ = ts_language_symbol_name.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_symbol_name", self, symbol); + } + return (MemorySegment)mh$.invokeExact(self, symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_symbol_for_name { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT, + TreeSitter.C_BOOL + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_symbol_for_name"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSSymbol ts_language_symbol_for_name(const TSLanguage *self, const char *string, uint32_t length, _Bool is_named) + * } + */ + public static FunctionDescriptor ts_language_symbol_for_name$descriptor() { + return ts_language_symbol_for_name.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSSymbol ts_language_symbol_for_name(const TSLanguage *self, const char *string, uint32_t length, _Bool is_named) + * } + */ + public static MethodHandle ts_language_symbol_for_name$handle() { + return ts_language_symbol_for_name.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSSymbol ts_language_symbol_for_name(const TSLanguage *self, const char *string, uint32_t length, _Bool is_named) + * } + */ + public static MemorySegment ts_language_symbol_for_name$address() { + return ts_language_symbol_for_name.ADDR; + } + + /** + * {@snippet lang=c : + * TSSymbol ts_language_symbol_for_name(const TSLanguage *self, const char *string, uint32_t length, _Bool is_named) + * } + */ + public static short ts_language_symbol_for_name(MemorySegment self, MemorySegment string, int length, boolean is_named) { + var mh$ = ts_language_symbol_for_name.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_symbol_for_name", self, string, length, is_named); + } + return (short)mh$.invokeExact(self, string, length, is_named); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_field_count { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_field_count"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_language_field_count(const TSLanguage *self) + * } + */ + public static FunctionDescriptor ts_language_field_count$descriptor() { + return ts_language_field_count.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_language_field_count(const TSLanguage *self) + * } + */ + public static MethodHandle ts_language_field_count$handle() { + return ts_language_field_count.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_language_field_count(const TSLanguage *self) + * } + */ + public static MemorySegment ts_language_field_count$address() { + return ts_language_field_count.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_language_field_count(const TSLanguage *self) + * } + */ + public static int ts_language_field_count(MemorySegment self) { + var mh$ = ts_language_field_count.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_field_count", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_field_name_for_id { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_SHORT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_field_name_for_id"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id) + * } + */ + public static FunctionDescriptor ts_language_field_name_for_id$descriptor() { + return ts_language_field_name_for_id.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id) + * } + */ + public static MethodHandle ts_language_field_name_for_id$handle() { + return ts_language_field_name_for_id.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id) + * } + */ + public static MemorySegment ts_language_field_name_for_id$address() { + return ts_language_field_name_for_id.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id) + * } + */ + public static MemorySegment ts_language_field_name_for_id(MemorySegment self, short id) { + var mh$ = ts_language_field_name_for_id.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_field_name_for_id", self, id); + } + return (MemorySegment)mh$.invokeExact(self, id); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_field_id_for_name { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_INT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_field_id_for_name"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length) + * } + */ + public static FunctionDescriptor ts_language_field_id_for_name$descriptor() { + return ts_language_field_id_for_name.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length) + * } + */ + public static MethodHandle ts_language_field_id_for_name$handle() { + return ts_language_field_id_for_name.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length) + * } + */ + public static MemorySegment ts_language_field_id_for_name$address() { + return ts_language_field_id_for_name.ADDR; + } + + /** + * {@snippet lang=c : + * TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length) + * } + */ + public static short ts_language_field_id_for_name(MemorySegment self, MemorySegment name, int name_length) { + var mh$ = ts_language_field_id_for_name.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_field_id_for_name", self, name, name_length); + } + return (short)mh$.invokeExact(self, name, name_length); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_symbol_type { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER, + TreeSitter.C_SHORT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_symbol_type"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol) + * } + */ + public static FunctionDescriptor ts_language_symbol_type$descriptor() { + return ts_language_symbol_type.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol) + * } + */ + public static MethodHandle ts_language_symbol_type$handle() { + return ts_language_symbol_type.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol) + * } + */ + public static MemorySegment ts_language_symbol_type$address() { + return ts_language_symbol_type.ADDR; + } + + /** + * {@snippet lang=c : + * TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol) + * } + */ + public static int ts_language_symbol_type(MemorySegment self, short symbol) { + var mh$ = ts_language_symbol_type.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_symbol_type", self, symbol); + } + return (int)mh$.invokeExact(self, symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_version { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_INT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_version"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * uint32_t ts_language_version(const TSLanguage *self) + * } + */ + public static FunctionDescriptor ts_language_version$descriptor() { + return ts_language_version.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * uint32_t ts_language_version(const TSLanguage *self) + * } + */ + public static MethodHandle ts_language_version$handle() { + return ts_language_version.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * uint32_t ts_language_version(const TSLanguage *self) + * } + */ + public static MemorySegment ts_language_version$address() { + return ts_language_version.ADDR; + } + + /** + * {@snippet lang=c : + * uint32_t ts_language_version(const TSLanguage *self) + * } + */ + public static int ts_language_version(MemorySegment self) { + var mh$ = ts_language_version.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_version", self); + } + return (int)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_language_next_state { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TreeSitter.C_POINTER, + TreeSitter.C_SHORT, + TreeSitter.C_SHORT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_language_next_state"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol) + * } + */ + public static FunctionDescriptor ts_language_next_state$descriptor() { + return ts_language_next_state.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol) + * } + */ + public static MethodHandle ts_language_next_state$handle() { + return ts_language_next_state.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol) + * } + */ + public static MemorySegment ts_language_next_state$address() { + return ts_language_next_state.ADDR; + } + + /** + * {@snippet lang=c : + * TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol) + * } + */ + public static short ts_language_next_state(MemorySegment self, short state, short symbol) { + var mh$ = ts_language_next_state.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_language_next_state", self, state, symbol); + } + return (short)mh$.invokeExact(self, state, symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_lookahead_iterator_new { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_SHORT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_lookahead_iterator_new"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state) + * } + */ + public static FunctionDescriptor ts_lookahead_iterator_new$descriptor() { + return ts_lookahead_iterator_new.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state) + * } + */ + public static MethodHandle ts_lookahead_iterator_new$handle() { + return ts_lookahead_iterator_new.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state) + * } + */ + public static MemorySegment ts_lookahead_iterator_new$address() { + return ts_lookahead_iterator_new.ADDR; + } + + /** + * {@snippet lang=c : + * TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state) + * } + */ + public static MemorySegment ts_lookahead_iterator_new(MemorySegment self, short state) { + var mh$ = ts_lookahead_iterator_new.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_lookahead_iterator_new", self, state); + } + return (MemorySegment)mh$.invokeExact(self, state); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_lookahead_iterator_delete { + public static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_lookahead_iterator_delete"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * void ts_lookahead_iterator_delete(TSLookaheadIterator *self) + * } + */ + public static FunctionDescriptor ts_lookahead_iterator_delete$descriptor() { + return ts_lookahead_iterator_delete.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * void ts_lookahead_iterator_delete(TSLookaheadIterator *self) + * } + */ + public static MethodHandle ts_lookahead_iterator_delete$handle() { + return ts_lookahead_iterator_delete.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * void ts_lookahead_iterator_delete(TSLookaheadIterator *self) + * } + */ + public static MemorySegment ts_lookahead_iterator_delete$address() { + return ts_lookahead_iterator_delete.ADDR; + } + + /** + * {@snippet lang=c : + * void ts_lookahead_iterator_delete(TSLookaheadIterator *self) + * } + */ + public static void ts_lookahead_iterator_delete(MemorySegment self) { + var mh$ = ts_lookahead_iterator_delete.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_lookahead_iterator_delete", self); + } + mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_lookahead_iterator_reset_state { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_SHORT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_lookahead_iterator_reset_state"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state) + * } + */ + public static FunctionDescriptor ts_lookahead_iterator_reset_state$descriptor() { + return ts_lookahead_iterator_reset_state.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state) + * } + */ + public static MethodHandle ts_lookahead_iterator_reset_state$handle() { + return ts_lookahead_iterator_reset_state.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state) + * } + */ + public static MemorySegment ts_lookahead_iterator_reset_state$address() { + return ts_lookahead_iterator_reset_state.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state) + * } + */ + public static boolean ts_lookahead_iterator_reset_state(MemorySegment self, short state) { + var mh$ = ts_lookahead_iterator_reset_state.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_lookahead_iterator_reset_state", self, state); + } + return (boolean)mh$.invokeExact(self, state); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_lookahead_iterator_reset { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER, + TreeSitter.C_POINTER, + TreeSitter.C_SHORT + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_lookahead_iterator_reset"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state) + * } + */ + public static FunctionDescriptor ts_lookahead_iterator_reset$descriptor() { + return ts_lookahead_iterator_reset.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state) + * } + */ + public static MethodHandle ts_lookahead_iterator_reset$handle() { + return ts_lookahead_iterator_reset.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state) + * } + */ + public static MemorySegment ts_lookahead_iterator_reset$address() { + return ts_lookahead_iterator_reset.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state) + * } + */ + public static boolean ts_lookahead_iterator_reset(MemorySegment self, MemorySegment language, short state) { + var mh$ = ts_lookahead_iterator_reset.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_lookahead_iterator_reset", self, language, state); + } + return (boolean)mh$.invokeExact(self, language, state); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_lookahead_iterator_language { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_lookahead_iterator_language"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self) + * } + */ + public static FunctionDescriptor ts_lookahead_iterator_language$descriptor() { + return ts_lookahead_iterator_language.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self) + * } + */ + public static MethodHandle ts_lookahead_iterator_language$handle() { + return ts_lookahead_iterator_language.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self) + * } + */ + public static MemorySegment ts_lookahead_iterator_language$address() { + return ts_lookahead_iterator_language.ADDR; + } + + /** + * {@snippet lang=c : + * const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self) + * } + */ + public static MemorySegment ts_lookahead_iterator_language(MemorySegment self) { + var mh$ = ts_lookahead_iterator_language.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_lookahead_iterator_language", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_lookahead_iterator_next { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_BOOL, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_lookahead_iterator_next"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_next(TSLookaheadIterator *self) + * } + */ + public static FunctionDescriptor ts_lookahead_iterator_next$descriptor() { + return ts_lookahead_iterator_next.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_next(TSLookaheadIterator *self) + * } + */ + public static MethodHandle ts_lookahead_iterator_next$handle() { + return ts_lookahead_iterator_next.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_next(TSLookaheadIterator *self) + * } + */ + public static MemorySegment ts_lookahead_iterator_next$address() { + return ts_lookahead_iterator_next.ADDR; + } + + /** + * {@snippet lang=c : + * _Bool ts_lookahead_iterator_next(TSLookaheadIterator *self) + * } + */ + public static boolean ts_lookahead_iterator_next(MemorySegment self) { + var mh$ = ts_lookahead_iterator_next.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_lookahead_iterator_next", self); + } + return (boolean)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_lookahead_iterator_current_symbol { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_SHORT, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_lookahead_iterator_current_symbol"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self) + * } + */ + public static FunctionDescriptor ts_lookahead_iterator_current_symbol$descriptor() { + return ts_lookahead_iterator_current_symbol.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self) + * } + */ + public static MethodHandle ts_lookahead_iterator_current_symbol$handle() { + return ts_lookahead_iterator_current_symbol.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self) + * } + */ + public static MemorySegment ts_lookahead_iterator_current_symbol$address() { + return ts_lookahead_iterator_current_symbol.ADDR; + } + + /** + * {@snippet lang=c : + * TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self) + * } + */ + public static short ts_lookahead_iterator_current_symbol(MemorySegment self) { + var mh$ = ts_lookahead_iterator_current_symbol.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_lookahead_iterator_current_symbol", self); + } + return (short)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + private static class ts_lookahead_iterator_current_symbol_name { + public static final FunctionDescriptor DESC = FunctionDescriptor.of( + TreeSitter.C_POINTER, + TreeSitter.C_POINTER + ); + + public static final MemorySegment ADDR = TreeSitter.findOrThrow("ts_lookahead_iterator_current_symbol_name"); + + public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); + } + + /** + * Function descriptor for: + * {@snippet lang=c : + * const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self) + * } + */ + public static FunctionDescriptor ts_lookahead_iterator_current_symbol_name$descriptor() { + return ts_lookahead_iterator_current_symbol_name.DESC; + } + + /** + * Downcall method handle for: + * {@snippet lang=c : + * const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self) + * } + */ + public static MethodHandle ts_lookahead_iterator_current_symbol_name$handle() { + return ts_lookahead_iterator_current_symbol_name.HANDLE; + } + + /** + * Address for: + * {@snippet lang=c : + * const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self) + * } + */ + public static MemorySegment ts_lookahead_iterator_current_symbol_name$address() { + return ts_lookahead_iterator_current_symbol_name.ADDR; + } + + /** + * {@snippet lang=c : + * const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self) + * } + */ + public static MemorySegment ts_lookahead_iterator_current_symbol_name(MemorySegment self) { + var mh$ = ts_lookahead_iterator_current_symbol_name.HANDLE; + try { + if (TRACE_DOWNCALLS) { + traceDowncall("ts_lookahead_iterator_current_symbol_name", self); + } + return (MemorySegment)mh$.invokeExact(self); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } +} + diff --git a/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/TreeSitterNativeLoaderTests.java b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/TreeSitterNativeLoaderTests.java new file mode 100644 index 000000000..b1d8aea17 --- /dev/null +++ b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/TreeSitterNativeLoaderTests.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import java.lang.foreign.MemorySegment; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.ts.TreeSitter; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TreeSitterNativeLoaderTests { + + @Test + @Tag("treesitter") + void loadMainLib() { + TreeSitterNativeLoader.initialize(); + MemorySegment segment = TreeSitter.ts_parser_new(); + assertThat(segment).isNotNull(); + } +} diff --git a/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/TreeSitterQueryTests.java b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/TreeSitterQueryTests.java new file mode 100644 index 000000000..f4e05d3cf --- /dev/null +++ b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/TreeSitterQueryTests.java @@ -0,0 +1,28 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +public class TreeSitterQueryTests { + + @Test + @Tag("treesitter") + void test1() { + + } +} diff --git a/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/AnyMatchTreeSitterQueryPredicateTests.java b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/AnyMatchTreeSitterQueryPredicateTests.java new file mode 100644 index 000000000..66987b0fb --- /dev/null +++ b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/AnyMatchTreeSitterQueryPredicateTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.TreeSitterNode; +import org.springframework.shell.treesitter.TreeSitterQueryCapture; +import org.springframework.shell.treesitter.TreeSitterQueryMatch; +import org.springframework.shell.treesitter.TreeSitterTree; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateContext; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +class AnyMatchTreeSitterQueryPredicateTests { + + @Test + void test1() { + TreeSitterTree tree = mock(TreeSitterTree.class); + TreeSitterNode node = mock(TreeSitterNode.class); + TreeSitterQueryMatch match = mock(TreeSitterQueryMatch.class); + TreeSitterQueryCapture tsqc = mock(TreeSitterQueryCapture.class); + doReturn("test").when(tsqc).getName(); + doReturn(List.of(tsqc)).when(match).getCaptures(); + doReturn(node).when(tsqc).getNode(); + doReturn(tree).when(node).getTree(); + doReturn(0).when(node).getStartByte(); + doReturn(11).when(node).getEndByte(); + doReturn("fakecontent".getBytes()).when(tree).getContent(); + + Pattern pattern1 = Pattern.compile("fakecontent"); + Pattern pattern2 = Pattern.compile("fakenotcontent"); + AnyMatchTreeSitterQueryPredicate predicate = new AnyMatchTreeSitterQueryPredicate("test", List.of(pattern1, pattern2)); + TreeSitterQueryPredicateContext context = new TreeSitterQueryPredicate.TreeSitterQueryPredicateContext(match); + boolean test = predicate.test(context); + assertThat(test).isTrue(); + } + +} diff --git a/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/AnyNotMatchTreeSitterQueryPredicateTests.java b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/AnyNotMatchTreeSitterQueryPredicateTests.java new file mode 100644 index 000000000..2b3146440 --- /dev/null +++ b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/AnyNotMatchTreeSitterQueryPredicateTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.TreeSitterNode; +import org.springframework.shell.treesitter.TreeSitterQueryCapture; +import org.springframework.shell.treesitter.TreeSitterQueryMatch; +import org.springframework.shell.treesitter.TreeSitterTree; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateContext; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +class AnyNotMatchTreeSitterQueryPredicateTests { + + @Test + void test1() { + TreeSitterTree tree = mock(TreeSitterTree.class); + TreeSitterNode node = mock(TreeSitterNode.class); + TreeSitterQueryMatch match = mock(TreeSitterQueryMatch.class); + TreeSitterQueryCapture tsqc = mock(TreeSitterQueryCapture.class); + doReturn("test").when(tsqc).getName(); + doReturn(List.of(tsqc)).when(match).getCaptures(); + doReturn(node).when(tsqc).getNode(); + doReturn(tree).when(node).getTree(); + doReturn(0).when(node).getStartByte(); + doReturn(11).when(node).getEndByte(); + doReturn("fakecontent".getBytes()).when(tree).getContent(); + + Pattern pattern1 = Pattern.compile("fakecontent1"); + Pattern pattern2 = Pattern.compile("fakecontent2"); + AnyNotMatchTreeSitterQueryPredicate predicate = new AnyNotMatchTreeSitterQueryPredicate("test", List.of(pattern1, pattern2)); + TreeSitterQueryPredicateContext context = new TreeSitterQueryPredicate.TreeSitterQueryPredicateContext(match); + boolean test = predicate.test(context); + assertThat(test).isTrue(); + } + +} diff --git a/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/BaseTreeSitterQueryPredicateTests.java b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/BaseTreeSitterQueryPredicateTests.java new file mode 100644 index 000000000..7afbdf76f --- /dev/null +++ b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/BaseTreeSitterQueryPredicateTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; + +import org.springframework.shell.treesitter.TreeSitterNode; +import org.springframework.shell.treesitter.TreeSitterQueryCapture; +import org.springframework.shell.treesitter.TreeSitterQueryMatch; +import org.springframework.shell.treesitter.TreeSitterTree; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateContext; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +class BaseTreeSitterQueryPredicateTests { + + TreeSitterQueryPredicateContext mockContext(String captureName, String captureContent) { + TreeSitterTree tree = mock(TreeSitterTree.class); + TreeSitterNode node = mock(TreeSitterNode.class); + TreeSitterQueryMatch match = mock(TreeSitterQueryMatch.class); + TreeSitterQueryCapture tsqc = mock(TreeSitterQueryCapture.class); + + doReturn(captureName).when(tsqc).getName(); + doReturn(List.of(tsqc)).when(match).getCaptures(); + doReturn(node).when(tsqc).getNode(); + doReturn(tree).when(node).getTree(); + doReturn(0).when(node).getStartByte(); + doReturn(captureContent.length()).when(node).getEndByte(); + doReturn(captureContent.getBytes()).when(tree).getContent(); + + return new TreeSitterQueryPredicate.TreeSitterQueryPredicateContext(match); + } +} diff --git a/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/MatchTreeSitterQueryPredicateTests.java b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/MatchTreeSitterQueryPredicateTests.java new file mode 100644 index 000000000..4b90eccbe --- /dev/null +++ b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/MatchTreeSitterQueryPredicateTests.java @@ -0,0 +1,67 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.TreeSitterNode; +import org.springframework.shell.treesitter.TreeSitterQueryCapture; +import org.springframework.shell.treesitter.TreeSitterQueryMatch; +import org.springframework.shell.treesitter.TreeSitterTree; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateContext; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +class MatchTreeSitterQueryPredicateTests extends BaseTreeSitterQueryPredicateTests { + + @Test + void test1() { + TreeSitterTree tree = mock(TreeSitterTree.class); + TreeSitterNode node = mock(TreeSitterNode.class); + TreeSitterQueryMatch match = mock(TreeSitterQueryMatch.class); + TreeSitterQueryCapture tsqc = mock(TreeSitterQueryCapture.class); + doReturn("test").when(tsqc).getName(); + doReturn(List.of(tsqc)).when(match).getCaptures(); + doReturn(node).when(tsqc).getNode(); + doReturn(tree).when(node).getTree(); + doReturn(0).when(node).getStartByte(); + doReturn(11).when(node).getEndByte(); + doReturn("fakecontent".getBytes()).when(tree).getContent(); + + Pattern pattern = Pattern.compile("fakecontent"); + MatchTreeSitterQueryPredicate predicate = new MatchTreeSitterQueryPredicate("test", pattern); + TreeSitterQueryPredicateContext context = new TreeSitterQueryPredicate.TreeSitterQueryPredicateContext(match); + boolean test = predicate.test(context); + assertThat(test).isTrue(); + } + + @Test + void test2() { + Pattern pattern = Pattern.compile("fakecontent"); + MatchTreeSitterQueryPredicate predicate = new MatchTreeSitterQueryPredicate("test", pattern); + + TreeSitterQueryPredicateContext ctx = mockContext("test", "fakecontent"); + boolean test = predicate.test(ctx); + + assertThat(test).isTrue(); + } + +} diff --git a/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/NotMatchTreeSitterQueryPredicateTests.java b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/NotMatchTreeSitterQueryPredicateTests.java new file mode 100644 index 000000000..8e2be012e --- /dev/null +++ b/spring-shell-treesitter/src/test/java/org/springframework/shell/treesitter/predicate/NotMatchTreeSitterQueryPredicateTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.treesitter.predicate; + +import java.util.List; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +import org.springframework.shell.treesitter.TreeSitterNode; +import org.springframework.shell.treesitter.TreeSitterQueryCapture; +import org.springframework.shell.treesitter.TreeSitterQueryMatch; +import org.springframework.shell.treesitter.TreeSitterTree; +import org.springframework.shell.treesitter.predicate.TreeSitterQueryPredicate.TreeSitterQueryPredicateContext; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +class NotMatchTreeSitterQueryPredicateTests { + + @Test + void test1() { + TreeSitterTree tree = mock(TreeSitterTree.class); + TreeSitterNode node = mock(TreeSitterNode.class); + TreeSitterQueryMatch match = mock(TreeSitterQueryMatch.class); + TreeSitterQueryCapture tsqc = mock(TreeSitterQueryCapture.class); + doReturn("test").when(tsqc).getName(); + doReturn(List.of(tsqc)).when(match).getCaptures(); + doReturn(node).when(tsqc).getNode(); + doReturn(tree).when(node).getTree(); + doReturn(0).when(node).getStartByte(); + doReturn(11).when(node).getEndByte(); + doReturn("fakecontent".getBytes()).when(tree).getContent(); + + // Pattern pattern = Pattern.compile("fakecontent"); + Pattern pattern = Pattern.compile("fakenotcontent"); + NotMatchTreeSitterQueryPredicate predicate = new NotMatchTreeSitterQueryPredicate("test", pattern); + TreeSitterQueryPredicateContext context = new TreeSitterQueryPredicate.TreeSitterQueryPredicateContext(match); + boolean test = predicate.test(context); + assertThat(test).isTrue(); + } + +} diff --git a/spring-shell-treesitter/src/ts/api.h b/spring-shell-treesitter/src/ts/api.h new file mode 100644 index 000000000..c1fbad254 --- /dev/null +++ b/spring-shell-treesitter/src/ts/api.h @@ -0,0 +1,1282 @@ +#ifndef TREE_SITTER_API_H_ +#define TREE_SITTER_API_H_ + +#ifndef TREE_SITTER_HIDE_SYMBOLS +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC visibility push(default) +#endif +#endif + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************/ +/* Section - ABI Versioning */ +/****************************/ + +/** + * The latest ABI version that is supported by the current version of the + * library. When Languages are generated by the Tree-sitter CLI, they are + * assigned an ABI version number that corresponds to the current CLI version. + * The Tree-sitter library is generally backwards-compatible with languages + * generated using older CLI versions, but is not forwards-compatible. + */ +#define TREE_SITTER_LANGUAGE_VERSION 14 + +/** + * The earliest ABI version that is supported by the current version of the + * library. + */ +#define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION 13 + +/*******************/ +/* Section - Types */ +/*******************/ + +typedef uint16_t TSStateId; +typedef uint16_t TSSymbol; +typedef uint16_t TSFieldId; +typedef struct TSLanguage TSLanguage; +typedef struct TSParser TSParser; +typedef struct TSTree TSTree; +typedef struct TSQuery TSQuery; +typedef struct TSQueryCursor TSQueryCursor; +typedef struct TSLookaheadIterator TSLookaheadIterator; + +typedef enum TSInputEncoding { + TSInputEncodingUTF8, + TSInputEncodingUTF16, +} TSInputEncoding; + +typedef enum TSSymbolType { + TSSymbolTypeRegular, + TSSymbolTypeAnonymous, + TSSymbolTypeAuxiliary, +} TSSymbolType; + +typedef struct TSPoint { + uint32_t row; + uint32_t column; +} TSPoint; + +typedef struct TSRange { + TSPoint start_point; + TSPoint end_point; + uint32_t start_byte; + uint32_t end_byte; +} TSRange; + +typedef struct TSInput { + void *payload; + const char *(*read)(void *payload, uint32_t byte_index, TSPoint position, uint32_t *bytes_read); + TSInputEncoding encoding; +} TSInput; + +typedef enum TSLogType { + TSLogTypeParse, + TSLogTypeLex, +} TSLogType; + +typedef struct TSLogger { + void *payload; + void (*log)(void *payload, TSLogType log_type, const char *buffer); +} TSLogger; + +typedef struct TSInputEdit { + uint32_t start_byte; + uint32_t old_end_byte; + uint32_t new_end_byte; + TSPoint start_point; + TSPoint old_end_point; + TSPoint new_end_point; +} TSInputEdit; + +typedef struct TSNode { + uint32_t context[4]; + const void *id; + const TSTree *tree; +} TSNode; + +typedef struct TSTreeCursor { + const void *tree; + const void *id; + uint32_t context[3]; +} TSTreeCursor; + +typedef struct TSQueryCapture { + TSNode node; + uint32_t index; +} TSQueryCapture; + +typedef enum TSQuantifier { + TSQuantifierZero = 0, // must match the array initialization value + TSQuantifierZeroOrOne, + TSQuantifierZeroOrMore, + TSQuantifierOne, + TSQuantifierOneOrMore, +} TSQuantifier; + +typedef struct TSQueryMatch { + uint32_t id; + uint16_t pattern_index; + uint16_t capture_count; + const TSQueryCapture *captures; +} TSQueryMatch; + +typedef enum TSQueryPredicateStepType { + TSQueryPredicateStepTypeDone, + TSQueryPredicateStepTypeCapture, + TSQueryPredicateStepTypeString, +} TSQueryPredicateStepType; + +typedef struct TSQueryPredicateStep { + TSQueryPredicateStepType type; + uint32_t value_id; +} TSQueryPredicateStep; + +typedef enum TSQueryError { + TSQueryErrorNone = 0, + TSQueryErrorSyntax, + TSQueryErrorNodeType, + TSQueryErrorField, + TSQueryErrorCapture, + TSQueryErrorStructure, + TSQueryErrorLanguage, +} TSQueryError; + +/********************/ +/* Section - Parser */ +/********************/ + +/** + * Create a new parser. + */ +TSParser *ts_parser_new(void); + +/** + * Delete the parser, freeing all of the memory that it used. + */ +void ts_parser_delete(TSParser *self); + +/** + * Get the parser's current language. + */ +const TSLanguage *ts_parser_language(const TSParser *self); + +/** + * Set the language that the parser should use for parsing. + * + * Returns a boolean indicating whether or not the language was successfully + * assigned. True means assignment succeeded. False means there was a version + * mismatch: the language was generated with an incompatible version of the + * Tree-sitter CLI. Check the language's version using [`ts_language_version`] + * and compare it to this library's [`TREE_SITTER_LANGUAGE_VERSION`] and + * [`TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION`] constants. + */ +bool ts_parser_set_language(TSParser *self, const TSLanguage *language); + +/** + * Set the ranges of text that the parser should include when parsing. + * + * By default, the parser will always include entire documents. This function + * allows you to parse only a *portion* of a document but still return a syntax + * tree whose ranges match up with the document as a whole. You can also pass + * multiple disjoint ranges. + * + * The second and third parameters specify the location and length of an array + * of ranges. The parser does *not* take ownership of these ranges; it copies + * the data, so it doesn't matter how these ranges are allocated. + * + * If `count` is zero, then the entire document will be parsed. Otherwise, + * the given ranges must be ordered from earliest to latest in the document, + * and they must not overlap. That is, the following must hold for all: + * + * `i < count - 1`: `ranges[i].end_byte <= ranges[i + 1].start_byte` + * + * If this requirement is not satisfied, the operation will fail, the ranges + * will not be assigned, and this function will return `false`. On success, + * this function returns `true` + */ +bool ts_parser_set_included_ranges( + TSParser *self, + const TSRange *ranges, + uint32_t count +); + +/** + * Get the ranges of text that the parser will include when parsing. + * + * The returned pointer is owned by the parser. The caller should not free it + * or write to it. The length of the array will be written to the given + * `count` pointer. + */ +const TSRange *ts_parser_included_ranges( + const TSParser *self, + uint32_t *count +); + +/** + * Use the parser to parse some source code and create a syntax tree. + * + * If you are parsing this document for the first time, pass `NULL` for the + * `old_tree` parameter. Otherwise, if you have already parsed an earlier + * version of this document and the document has since been edited, pass the + * previous syntax tree so that the unchanged parts of it can be reused. + * This will save time and memory. For this to work correctly, you must have + * already edited the old syntax tree using the [`ts_tree_edit`] function in a + * way that exactly matches the source code changes. + * + * The [`TSInput`] parameter lets you specify how to read the text. It has the + * following three fields: + * 1. [`read`]: A function to retrieve a chunk of text at a given byte offset + * and (row, column) position. The function should return a pointer to the + * text and write its length to the [`bytes_read`] pointer. The parser does + * not take ownership of this buffer; it just borrows it until it has + * finished reading it. The function should write a zero value to the + * [`bytes_read`] pointer to indicate the end of the document. + * 2. [`payload`]: An arbitrary pointer that will be passed to each invocation + * of the [`read`] function. + * 3. [`encoding`]: An indication of how the text is encoded. Either + * `TSInputEncodingUTF8` or `TSInputEncodingUTF16`. + * + * This function returns a syntax tree on success, and `NULL` on failure. There + * are three possible reasons for failure: + * 1. The parser does not have a language assigned. Check for this using the + [`ts_parser_language`] function. + * 2. Parsing was cancelled due to a timeout that was set by an earlier call to + * the [`ts_parser_set_timeout_micros`] function. You can resume parsing from + * where the parser left out by calling [`ts_parser_parse`] again with the + * same arguments. Or you can start parsing from scratch by first calling + * [`ts_parser_reset`]. + * 3. Parsing was cancelled using a cancellation flag that was set by an + * earlier call to [`ts_parser_set_cancellation_flag`]. You can resume parsing + * from where the parser left out by calling [`ts_parser_parse`] again with + * the same arguments. + * + * [`read`]: TSInput::read + * [`payload`]: TSInput::payload + * [`encoding`]: TSInput::encoding + * [`bytes_read`]: TSInput::read + */ +TSTree *ts_parser_parse( + TSParser *self, + const TSTree *old_tree, + TSInput input +); + +/** + * Use the parser to parse some source code stored in one contiguous buffer. + * The first two parameters are the same as in the [`ts_parser_parse`] function + * above. The second two parameters indicate the location of the buffer and its + * length in bytes. + */ +TSTree *ts_parser_parse_string( + TSParser *self, + const TSTree *old_tree, + const char *string, + uint32_t length +); + +/** + * Use the parser to parse some source code stored in one contiguous buffer with + * a given encoding. The first four parameters work the same as in the + * [`ts_parser_parse_string`] method above. The final parameter indicates whether + * the text is encoded as UTF8 or UTF16. + */ +TSTree *ts_parser_parse_string_encoding( + TSParser *self, + const TSTree *old_tree, + const char *string, + uint32_t length, + TSInputEncoding encoding +); + +/** + * Instruct the parser to start the next parse from the beginning. + * + * If the parser previously failed because of a timeout or a cancellation, then + * by default, it will resume where it left off on the next call to + * [`ts_parser_parse`] or other parsing functions. If you don't want to resume, + * and instead intend to use this parser to parse some other document, you must + * call [`ts_parser_reset`] first. + */ +void ts_parser_reset(TSParser *self); + +/** + * Set the maximum duration in microseconds that parsing should be allowed to + * take before halting. + * + * If parsing takes longer than this, it will halt early, returning NULL. + * See [`ts_parser_parse`] for more information. + */ +void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros); + +/** + * Get the duration in microseconds that parsing is allowed to take. + */ +uint64_t ts_parser_timeout_micros(const TSParser *self); + +/** + * Set the parser's current cancellation flag pointer. + * + * If a non-null pointer is assigned, then the parser will periodically read + * from this pointer during parsing. If it reads a non-zero value, it will + * halt early, returning NULL. See [`ts_parser_parse`] for more information. + */ +void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag); + +/** + * Get the parser's current cancellation flag pointer. + */ +const size_t *ts_parser_cancellation_flag(const TSParser *self); + +/** + * Set the logger that a parser should use during parsing. + * + * The parser does not take ownership over the logger payload. If a logger was + * previously assigned, the caller is responsible for releasing any memory + * owned by the previous logger. + */ +void ts_parser_set_logger(TSParser *self, TSLogger logger); + +/** + * Get the parser's current logger. + */ +TSLogger ts_parser_logger(const TSParser *self); + +/** + * Set the file descriptor to which the parser should write debugging graphs + * during parsing. The graphs are formatted in the DOT language. You may want + * to pipe these graphs directly to a `dot(1)` process in order to generate + * SVG output. You can turn off this logging by passing a negative number. + */ +void ts_parser_print_dot_graphs(TSParser *self, int fd); + +/******************/ +/* Section - Tree */ +/******************/ + +/** + * Create a shallow copy of the syntax tree. This is very fast. + * + * You need to copy a syntax tree in order to use it on more than one thread at + * a time, as syntax trees are not thread safe. + */ +TSTree *ts_tree_copy(const TSTree *self); + +/** + * Delete the syntax tree, freeing all of the memory that it used. + */ +void ts_tree_delete(TSTree *self); + +/** + * Get the root node of the syntax tree. + */ +TSNode ts_tree_root_node(const TSTree *self); + +/** + * Get the root node of the syntax tree, but with its position + * shifted forward by the given offset. + */ +TSNode ts_tree_root_node_with_offset( + const TSTree *self, + uint32_t offset_bytes, + TSPoint offset_extent +); + +/** + * Get the language that was used to parse the syntax tree. + */ +const TSLanguage *ts_tree_language(const TSTree *self); + +/** + * Get the array of included ranges that was used to parse the syntax tree. + * + * The returned pointer must be freed by the caller. + */ +TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length); + +/** + * Edit the syntax tree to keep it in sync with source code that has been + * edited. + * + * You must describe the edit both in terms of byte offsets and in terms of + * (row, column) coordinates. + */ +void ts_tree_edit(TSTree *self, const TSInputEdit *edit); + +/** + * Compare an old edited syntax tree to a new syntax tree representing the same + * document, returning an array of ranges whose syntactic structure has changed. + * + * For this to work correctly, the old syntax tree must have been edited such + * that its ranges match up to the new tree. Generally, you'll want to call + * this function right after calling one of the [`ts_parser_parse`] functions. + * You need to pass the old tree that was passed to parse, as well as the new + * tree that was returned from that function. + * + * The returned array is allocated using `malloc` and the caller is responsible + * for freeing it using `free`. The length of the array will be written to the + * given `length` pointer. + */ +TSRange *ts_tree_get_changed_ranges( + const TSTree *old_tree, + const TSTree *new_tree, + uint32_t *length +); + +/** + * Write a DOT graph describing the syntax tree to the given file. + */ +void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor); + +/******************/ +/* Section - Node */ +/******************/ + +/** + * Get the node's type as a null-terminated string. + */ +const char *ts_node_type(TSNode self); + +/** + * Get the node's type as a numerical id. + */ +TSSymbol ts_node_symbol(TSNode self); + +/** + * Get the node's language. + */ +const TSLanguage *ts_node_language(TSNode self); + +/** + * Get the node's type as it appears in the grammar ignoring aliases as a + * null-terminated string. + */ +const char *ts_node_grammar_type(TSNode self); + +/** + * Get the node's type as a numerical id as it appears in the grammar ignoring + * aliases. This should be used in [`ts_language_next_state`] instead of + * [`ts_node_symbol`]. + */ +TSSymbol ts_node_grammar_symbol(TSNode self); + +/** + * Get the node's start byte. + */ +uint32_t ts_node_start_byte(TSNode self); + +/** + * Get the node's start position in terms of rows and columns. + */ +TSPoint ts_node_start_point(TSNode self); + +/** + * Get the node's end byte. + */ +uint32_t ts_node_end_byte(TSNode self); + +/** + * Get the node's end position in terms of rows and columns. + */ +TSPoint ts_node_end_point(TSNode self); + +/** + * Get an S-expression representing the node as a string. + * + * This string is allocated with `malloc` and the caller is responsible for + * freeing it using `free`. + */ +char *ts_node_string(TSNode self); + +/** + * Check if the node is null. Functions like [`ts_node_child`] and + * [`ts_node_next_sibling`] will return a null node to indicate that no such node + * was found. + */ +bool ts_node_is_null(TSNode self); + +/** + * Check if the node is *named*. Named nodes correspond to named rules in the + * grammar, whereas *anonymous* nodes correspond to string literals in the + * grammar. + */ +bool ts_node_is_named(TSNode self); + +/** + * Check if the node is *missing*. Missing nodes are inserted by the parser in + * order to recover from certain kinds of syntax errors. + */ +bool ts_node_is_missing(TSNode self); + +/** + * Check if the node is *extra*. Extra nodes represent things like comments, + * which are not required the grammar, but can appear anywhere. + */ +bool ts_node_is_extra(TSNode self); + +/** + * Check if a syntax node has been edited. + */ +bool ts_node_has_changes(TSNode self); + +/** + * Check if the node is a syntax error or contains any syntax errors. + */ +bool ts_node_has_error(TSNode self); + +/** + * Check if the node is a syntax error. +*/ +bool ts_node_is_error(TSNode self); + +/** + * Get this node's parse state. +*/ +TSStateId ts_node_parse_state(TSNode self); + +/** + * Get the parse state after this node. +*/ +TSStateId ts_node_next_parse_state(TSNode self); + +/** + * Get the node's immediate parent. + * Prefer [`ts_node_child_containing_descendant`] for + * iterating over the node's ancestors. + */ +TSNode ts_node_parent(TSNode self); + +/** + * Get the node's child that contains `descendant`. + */ +TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant); + +/** + * Get the node's child at the given index, where zero represents the first + * child. + */ +TSNode ts_node_child(TSNode self, uint32_t child_index); + +/** + * Get the field name for node's child at the given index, where zero represents + * the first child. Returns NULL, if no field is found. + */ +const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index); + +/** + * Get the node's number of children. + */ +uint32_t ts_node_child_count(TSNode self); + +/** + * Get the node's *named* child at the given index. + * + * See also [`ts_node_is_named`]. + */ +TSNode ts_node_named_child(TSNode self, uint32_t child_index); + +/** + * Get the node's number of *named* children. + * + * See also [`ts_node_is_named`]. + */ +uint32_t ts_node_named_child_count(TSNode self); + +/** + * Get the node's child with the given field name. + */ +TSNode ts_node_child_by_field_name( + TSNode self, + const char *name, + uint32_t name_length +); + +/** + * Get the node's child with the given numerical field id. + * + * You can convert a field name to an id using the + * [`ts_language_field_id_for_name`] function. + */ +TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id); + +/** + * Get the node's next / previous sibling. + */ +TSNode ts_node_next_sibling(TSNode self); +TSNode ts_node_prev_sibling(TSNode self); + +/** + * Get the node's next / previous *named* sibling. + */ +TSNode ts_node_next_named_sibling(TSNode self); +TSNode ts_node_prev_named_sibling(TSNode self); + +/** + * Get the node's first child that extends beyond the given byte offset. + */ +TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte); + +/** + * Get the node's first named child that extends beyond the given byte offset. + */ +TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte); + +/** + * Get the node's number of descendants, including one for the node itself. + */ +uint32_t ts_node_descendant_count(TSNode self); + +/** + * Get the smallest node within this node that spans the given range of bytes + * or (row, column) positions. + */ +TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end); +TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end); + +/** + * Get the smallest named node within this node that spans the given range of + * bytes or (row, column) positions. + */ +TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end); +TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end); + +/** + * Edit the node to keep it in-sync with source code that has been edited. + * + * This function is only rarely needed. When you edit a syntax tree with the + * [`ts_tree_edit`] function, all of the nodes that you retrieve from the tree + * afterward will already reflect the edit. You only need to use [`ts_node_edit`] + * when you have a [`TSNode`] instance that you want to keep and continue to use + * after an edit. + */ +void ts_node_edit(TSNode *self, const TSInputEdit *edit); + +/** + * Check if two nodes are identical. + */ +bool ts_node_eq(TSNode self, TSNode other); + +/************************/ +/* Section - TreeCursor */ +/************************/ + +/** + * Create a new tree cursor starting from the given node. + * + * A tree cursor allows you to walk a syntax tree more efficiently than is + * possible using the [`TSNode`] functions. It is a mutable object that is always + * on a certain syntax node, and can be moved imperatively to different nodes. + */ +TSTreeCursor ts_tree_cursor_new(TSNode node); + +/** + * Delete a tree cursor, freeing all of the memory that it used. + */ +void ts_tree_cursor_delete(TSTreeCursor *self); + +/** + * Re-initialize a tree cursor to start at the original node that the cursor was + * constructed with. + */ +void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node); + +/** + * Re-initialize a tree cursor to the same position as another cursor. + * + * Unlike [`ts_tree_cursor_reset`], this will not lose parent information and + * allows reusing already created cursors. +*/ +void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src); + +/** + * Get the tree cursor's current node. + */ +TSNode ts_tree_cursor_current_node(const TSTreeCursor *self); + +/** + * Get the field name of the tree cursor's current node. + * + * This returns `NULL` if the current node doesn't have a field. + * See also [`ts_node_child_by_field_name`]. + */ +const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self); + +/** + * Get the field id of the tree cursor's current node. + * + * This returns zero if the current node doesn't have a field. + * See also [`ts_node_child_by_field_id`], [`ts_language_field_id_for_name`]. + */ +TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self); + +/** + * Move the cursor to the parent of its current node. + * + * This returns `true` if the cursor successfully moved, and returns `false` + * if there was no parent node (the cursor was already on the root node). + */ +bool ts_tree_cursor_goto_parent(TSTreeCursor *self); + +/** + * Move the cursor to the next sibling of its current node. + * + * This returns `true` if the cursor successfully moved, and returns `false` + * if there was no next sibling node. + */ +bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self); + +/** + * Move the cursor to the previous sibling of its current node. + * + * This returns `true` if the cursor successfully moved, and returns `false` if + * there was no previous sibling node. + * + * Note, that this function may be slower than + * [`ts_tree_cursor_goto_next_sibling`] due to how node positions are stored. In + * the worst case, this will need to iterate through all the children upto the + * previous sibling node to recalculate its position. + */ +bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self); + +/** + * Move the cursor to the first child of its current node. + * + * This returns `true` if the cursor successfully moved, and returns `false` + * if there were no children. + */ +bool ts_tree_cursor_goto_first_child(TSTreeCursor *self); + +/** + * Move the cursor to the last child of its current node. + * + * This returns `true` if the cursor successfully moved, and returns `false` if + * there were no children. + * + * Note that this function may be slower than [`ts_tree_cursor_goto_first_child`] + * because it needs to iterate through all the children to compute the child's + * position. + */ +bool ts_tree_cursor_goto_last_child(TSTreeCursor *self); + +/** + * Move the cursor to the node that is the nth descendant of + * the original node that the cursor was constructed with, where + * zero represents the original node itself. + */ +void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index); + +/** + * Get the index of the cursor's current node out of all of the + * descendants of the original node that the cursor was constructed with. + */ +uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self); + +/** + * Get the depth of the cursor's current node relative to the original + * node that the cursor was constructed with. + */ +uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self); + +/** + * Move the cursor to the first child of its current node that extends beyond + * the given byte offset or point. + * + * This returns the index of the child node if one was found, and returns -1 + * if no such child was found. + */ +int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte); +int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point); + +TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor); + +/*******************/ +/* Section - Query */ +/*******************/ + +/** + * Create a new query from a string containing one or more S-expression + * patterns. The query is associated with a particular language, and can + * only be run on syntax nodes parsed with that language. + * + * If all of the given patterns are valid, this returns a [`TSQuery`]. + * If a pattern is invalid, this returns `NULL`, and provides two pieces + * of information about the problem: + * 1. The byte offset of the error is written to the `error_offset` parameter. + * 2. The type of error is written to the `error_type` parameter. + */ +TSQuery *ts_query_new( + const TSLanguage *language, + const char *source, + uint32_t source_len, + uint32_t *error_offset, + TSQueryError *error_type +); + +/** + * Delete a query, freeing all of the memory that it used. + */ +void ts_query_delete(TSQuery *self); + +/** + * Get the number of patterns, captures, or string literals in the query. + */ +uint32_t ts_query_pattern_count(const TSQuery *self); +uint32_t ts_query_capture_count(const TSQuery *self); +uint32_t ts_query_string_count(const TSQuery *self); + +/** + * Get the byte offset where the given pattern starts in the query's source. + * + * This can be useful when combining queries by concatenating their source + * code strings. + */ +uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index); + +/** + * Get the byte offset where the given pattern ends in the query's source. + * + * This can be useful when combining queries by concatenating their source + * code strings. + */ +uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index); + +/** + * Get all of the predicates for the given pattern in the query. + * + * The predicates are represented as a single array of steps. There are three + * types of steps in this array, which correspond to the three legal values for + * the `type` field: + * - `TSQueryPredicateStepTypeCapture` - Steps with this type represent names + * of captures. Their `value_id` can be used with the + * [`ts_query_capture_name_for_id`] function to obtain the name of the capture. + * - `TSQueryPredicateStepTypeString` - Steps with this type represent literal + * strings. Their `value_id` can be used with the + * [`ts_query_string_value_for_id`] function to obtain their string value. + * - `TSQueryPredicateStepTypeDone` - Steps with this type are *sentinels* + * that represent the end of an individual predicate. If a pattern has two + * predicates, then there will be two steps with this `type` in the array. + */ +const TSQueryPredicateStep *ts_query_predicates_for_pattern( + const TSQuery *self, + uint32_t pattern_index, + uint32_t *step_count +); + +/* + * Check if the given pattern in the query has a single root node. + */ +bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index); + +/* + * Check if the given pattern in the query is 'non local'. + * + * A non-local pattern has multiple root nodes and can match within a + * repeating sequence of nodes, as specified by the grammar. Non-local + * patterns disable certain optimizations that would otherwise be possible + * when executing a query on a specific range of a syntax tree. + */ +bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index); + +/* + * Check if a given pattern is guaranteed to match once a given step is reached. + * The step is specified by its byte offset in the query's source code. + */ +bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset); + +/** + * Get the name and length of one of the query's captures, or one of the + * query's string literals. Each capture and string is associated with a + * numeric id based on the order that it appeared in the query's source. + */ +const char *ts_query_capture_name_for_id( + const TSQuery *self, + uint32_t index, + uint32_t *length +); + +/** + * Get the quantifier of the query's captures. Each capture is * associated + * with a numeric id based on the order that it appeared in the query's source. + */ +TSQuantifier ts_query_capture_quantifier_for_id( + const TSQuery *self, + uint32_t pattern_index, + uint32_t capture_index +); + +const char *ts_query_string_value_for_id( + const TSQuery *self, + uint32_t index, + uint32_t *length +); + +/** + * Disable a certain capture within a query. + * + * This prevents the capture from being returned in matches, and also avoids + * any resource usage associated with recording the capture. Currently, there + * is no way to undo this. + */ +void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length); + +/** + * Disable a certain pattern within a query. + * + * This prevents the pattern from matching and removes most of the overhead + * associated with the pattern. Currently, there is no way to undo this. + */ +void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index); + +/** + * Create a new cursor for executing a given query. + * + * The cursor stores the state that is needed to iteratively search + * for matches. To use the query cursor, first call [`ts_query_cursor_exec`] + * to start running a given query on a given syntax node. Then, there are + * two options for consuming the results of the query: + * 1. Repeatedly call [`ts_query_cursor_next_match`] to iterate over all of the + * *matches* in the order that they were found. Each match contains the + * index of the pattern that matched, and an array of captures. Because + * multiple patterns can match the same set of nodes, one match may contain + * captures that appear *before* some of the captures from a previous match. + * 2. Repeatedly call [`ts_query_cursor_next_capture`] to iterate over all of the + * individual *captures* in the order that they appear. This is useful if + * don't care about which pattern matched, and just want a single ordered + * sequence of captures. + * + * If you don't care about consuming all of the results, you can stop calling + * [`ts_query_cursor_next_match`] or [`ts_query_cursor_next_capture`] at any point. + * You can then start executing another query on another node by calling + * [`ts_query_cursor_exec`] again. + */ +TSQueryCursor *ts_query_cursor_new(void); + +/** + * Delete a query cursor, freeing all of the memory that it used. + */ +void ts_query_cursor_delete(TSQueryCursor *self); + +/** + * Start running a given query on a given node. + */ +void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node); + +/** + * Manage the maximum number of in-progress matches allowed by this query + * cursor. + * + * Query cursors have an optional maximum capacity for storing lists of + * in-progress captures. If this capacity is exceeded, then the + * earliest-starting match will silently be dropped to make room for further + * matches. This maximum capacity is optional — by default, query cursors allow + * any number of pending matches, dynamically allocating new space for them as + * needed as the query is executed. + */ +bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self); +uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self); +void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit); + +/** + * Set the range of bytes or (row, column) positions in which the query + * will be executed. + */ +void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte); +void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point); + +/** + * Advance to the next match of the currently running query. + * + * If there is a match, write it to `*match` and return `true`. + * Otherwise, return `false`. + */ +bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match); +void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id); + +/** + * Advance to the next capture of the currently running query. + * + * If there is a capture, write its match to `*match` and its index within + * the matche's capture list to `*capture_index`. Otherwise, return `false`. + */ +bool ts_query_cursor_next_capture( + TSQueryCursor *self, + TSQueryMatch *match, + uint32_t *capture_index +); + +/** + * Set the maximum start depth for a query cursor. + * + * This prevents cursors from exploring children nodes at a certain depth. + * Note if a pattern includes many children, then they will still be checked. + * + * The zero max start depth value can be used as a special behavior and + * it helps to destructure a subtree by staying on a node and using captures + * for interested parts. Note that the zero max start depth only limit a search + * depth for a pattern's root node but other nodes that are parts of the pattern + * may be searched at any depth what defined by the pattern structure. + * + * Set to `UINT32_MAX` to remove the maximum start depth. + */ +void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth); + +/**********************/ +/* Section - Language */ +/**********************/ + +/** + * Get another reference to the given language. + */ +const TSLanguage *ts_language_copy(const TSLanguage *self); + +/** + * Free any dynamically-allocated resources for this language, if + * this is the last reference. + */ +void ts_language_delete(const TSLanguage *self); + +/** + * Get the number of distinct node types in the language. + */ +uint32_t ts_language_symbol_count(const TSLanguage *self); + +/** + * Get the number of valid states in this language. +*/ +uint32_t ts_language_state_count(const TSLanguage *self); + +/** + * Get a node type string for the given numerical id. + */ +const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol); + +/** + * Get the numerical id for the given node type string. + */ +TSSymbol ts_language_symbol_for_name( + const TSLanguage *self, + const char *string, + uint32_t length, + bool is_named +); + +/** + * Get the number of distinct field names in the language. + */ +uint32_t ts_language_field_count(const TSLanguage *self); + +/** + * Get the field name string for the given numerical id. + */ +const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id); + +/** + * Get the numerical id for the given field name string. + */ +TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length); + +/** + * Check whether the given node type id belongs to named nodes, anonymous nodes, + * or a hidden nodes. + * + * See also [`ts_node_is_named`]. Hidden nodes are never returned from the API. + */ +TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol); + +/** + * Get the ABI version number for this language. This version number is used + * to ensure that languages were generated by a compatible version of + * Tree-sitter. + * + * See also [`ts_parser_set_language`]. + */ +uint32_t ts_language_version(const TSLanguage *self); + +/** + * Get the next parse state. Combine this with lookahead iterators to generate + * completion suggestions or valid symbols in error nodes. Use + * [`ts_node_grammar_symbol`] for valid symbols. +*/ +TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol); + +/********************************/ +/* Section - Lookahead Iterator */ +/********************************/ + +/** + * Create a new lookahead iterator for the given language and parse state. + * + * This returns `NULL` if state is invalid for the language. + * + * Repeatedly using [`ts_lookahead_iterator_next`] and + * [`ts_lookahead_iterator_current_symbol`] will generate valid symbols in the + * given parse state. Newly created lookahead iterators will contain the `ERROR` + * symbol. + * + * Lookahead iterators can be useful to generate suggestions and improve syntax + * error diagnostics. To get symbols valid in an ERROR node, use the lookahead + * iterator on its first leaf node state. For `MISSING` nodes, a lookahead + * iterator created on the previous non-extra leaf node may be appropriate. +*/ +TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state); + +/** + * Delete a lookahead iterator freeing all the memory used. +*/ +void ts_lookahead_iterator_delete(TSLookaheadIterator *self); + +/** + * Reset the lookahead iterator to another state. + * + * This returns `true` if the iterator was reset to the given state and `false` + * otherwise. +*/ +bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state); + +/** + * Reset the lookahead iterator. + * + * This returns `true` if the language was set successfully and `false` + * otherwise. +*/ +bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state); + +/** + * Get the current language of the lookahead iterator. +*/ +const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self); + +/** + * Advance the lookahead iterator to the next symbol. + * + * This returns `true` if there is a new symbol and `false` otherwise. +*/ +bool ts_lookahead_iterator_next(TSLookaheadIterator *self); + +/** + * Get the current symbol of the lookahead iterator; +*/ +TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self); + +/** + * Get the current symbol type of the lookahead iterator as a null terminated + * string. +*/ +const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self); + +/*************************************/ +/* Section - WebAssembly Integration */ +/************************************/ + +typedef struct wasm_engine_t TSWasmEngine; +typedef struct TSWasmStore TSWasmStore; + +typedef enum { + TSWasmErrorKindNone = 0, + TSWasmErrorKindParse, + TSWasmErrorKindCompile, + TSWasmErrorKindInstantiate, + TSWasmErrorKindAllocate, +} TSWasmErrorKind; + +typedef struct { + TSWasmErrorKind kind; + char *message; +} TSWasmError; + +/** + * Create a Wasm store. + */ +TSWasmStore *ts_wasm_store_new( + TSWasmEngine *engine, + TSWasmError *error +); + +/** + * Free the memory associated with the given Wasm store. + */ +void ts_wasm_store_delete(TSWasmStore *); + +/** + * Create a language from a buffer of Wasm. The resulting language behaves + * like any other Tree-sitter language, except that in order to use it with + * a parser, that parser must have a Wasm store. Note that the language + * can be used with any Wasm store, it doesn't need to be the same store that + * was used to originally load it. + */ +const TSLanguage *ts_wasm_store_load_language( + TSWasmStore *, + const char *name, + const char *wasm, + uint32_t wasm_len, + TSWasmError *error +); + +/** + * Get the number of languages instantiated in the given wasm store. + */ +size_t ts_wasm_store_language_count(const TSWasmStore *); + +/** + * Check if the language came from a Wasm module. If so, then in order to use + * this language with a Parser, that parser must have a Wasm store assigned. + */ +bool ts_language_is_wasm(const TSLanguage *); + +/** + * Assign the given Wasm store to the parser. A parser must have a Wasm store + * in order to use Wasm languages. + */ +void ts_parser_set_wasm_store(TSParser *, TSWasmStore *); + +/** + * Remove the parser's current Wasm store and return it. This returns NULL if + * the parser doesn't have a Wasm store. + */ +TSWasmStore *ts_parser_take_wasm_store(TSParser *); + +/**********************************/ +/* Section - Global Configuration */ +/**********************************/ + +/** + * Set the allocation functions used by the library. + * + * By default, Tree-sitter uses the standard libc allocation functions, + * but aborts the process when an allocation fails. This function lets + * you supply alternative allocation functions at runtime. + * + * If you pass `NULL` for any parameter, Tree-sitter will switch back to + * its default implementation of that function. + * + * If you call this function after the library has already been used, then + * you must ensure that either: + * 1. All the existing objects have been freed. + * 2. The new allocator shares its state with the old one, so it is capable + * of freeing memory that was allocated by the old allocator. + */ +void ts_set_allocator( + void *(*new_malloc)(size_t), + void *(*new_calloc)(size_t, size_t), + void *(*new_realloc)(void *, size_t), + void (*new_free)(void *) +); + +#ifdef __cplusplus +} +#endif + +#ifndef TREE_SITTER_HIDE_SYMBOLS +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC visibility pop +#endif +#endif + +#endif // TREE_SITTER_API_H_