├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ ├── lint.yml │ └── publish.yml ├── .gitignore ├── CMakeLists.txt ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── Package.resolved ├── Package.swift ├── README.md ├── binding.gyp ├── bindings ├── c │ ├── tree-sitter-ql.h │ └── tree-sitter-ql.pc.in ├── go │ ├── binding.go │ └── binding_test.go ├── node │ ├── binding.cc │ ├── binding_test.js │ ├── index.d.ts │ └── index.js ├── python │ ├── tests │ │ └── test_binding.py │ └── tree_sitter_ql │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed ├── rust │ ├── build.rs │ └── lib.rs └── swift │ ├── TreeSitterQL │ └── ql.h │ └── TreeSitterQLTests │ └── TreeSitterQLTests.swift ├── eslint.config.mjs ├── go.mod ├── go.sum ├── grammar.js ├── package-lock.json ├── package.json ├── pyproject.toml ├── queries ├── highlights.scm └── tags.scm ├── setup.py ├── src ├── grammar.json ├── node-types.json ├── parser.c └── tree_sitter │ ├── alloc.h │ ├── array.h │ └── parser.h ├── test └── corpus │ ├── basic.txt │ ├── class.txt │ ├── ctf.txt │ ├── expr.txt │ ├── formula.txt │ ├── modules.txt │ ├── operators_and_precedence.txt │ ├── predicates.txt │ └── primary.txt └── tree-sitter.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | 6 | [*.{json,toml,yml,gyp}] 7 | indent_style = space 8 | indent_size = 2 9 | 10 | [*.js] 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.scm] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [*.{c,cc,h}] 19 | indent_style = space 20 | indent_size = 4 21 | 22 | [*.rs] 23 | indent_style = space 24 | indent_size = 4 25 | 26 | [*.{py,pyi}] 27 | indent_style = space 28 | indent_size = 4 29 | 30 | [*.swift] 31 | indent_style = space 32 | indent_size = 4 33 | 34 | [*.go] 35 | indent_style = tab 36 | indent_size = 8 37 | 38 | [Makefile] 39 | indent_style = tab 40 | indent_size = 8 41 | 42 | [parser.c] 43 | indent_size = 2 44 | 45 | [{alloc,array,parser}.h] 46 | indent_size = 2 47 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | 3 | # Generated source files 4 | src/*.json linguist-generated 5 | src/parser.c linguist-generated 6 | src/tree_sitter/* linguist-generated 7 | 8 | # C bindings 9 | bindings/c/* linguist-generated 10 | CMakeLists.txt linguist-generated 11 | Makefile linguist-generated 12 | 13 | # Rust bindings 14 | bindings/rust/* linguist-generated 15 | Cargo.toml linguist-generated 16 | Cargo.lock linguist-generated 17 | 18 | # Node.js bindings 19 | bindings/node/* linguist-generated 20 | binding.gyp linguist-generated 21 | package.json linguist-generated 22 | package-lock.json linguist-generated 23 | 24 | # Python bindings 25 | bindings/python/** linguist-generated 26 | setup.py linguist-generated 27 | pyproject.toml linguist-generated 28 | 29 | # Go bindings 30 | bindings/go/* linguist-generated 31 | go.mod linguist-generated 32 | go.sum linguist-generated 33 | 34 | # Swift bindings 35 | bindings/swift/** linguist-generated 36 | Package.swift linguist-generated 37 | Package.resolved linguist-generated 38 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - grammar.js 8 | - src/** 9 | - test/** 10 | - bindings/** 11 | - binding.gyp 12 | pull_request: 13 | paths: 14 | - grammar.js 15 | - src/** 16 | - test/** 17 | - bindings/** 18 | - binding.gyp 19 | 20 | concurrency: 21 | group: ${{github.workflow}}-${{github.ref}} 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | test: 26 | name: Test parser 27 | runs-on: ${{matrix.os}} 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | os: [ubuntu-latest, windows-latest, macos-14] 32 | steps: 33 | - name: Checkout repository 34 | uses: actions/checkout@v4 35 | - name: Set up the repo 36 | uses: tree-sitter/setup-action/cli@v1 37 | - name: Set up examples 38 | run: |- 39 | git clone https://github.com/github/codeql examples/codeql --single-branch --depth=1 --filter=blob:none 40 | - name: Run tests 41 | uses: tree-sitter/parser-test-action@v2 42 | with: 43 | test-rust: true 44 | test-node: true 45 | test-python: true 46 | test-go: true 47 | test-swift: true 48 | - name: Parse examples 49 | uses: tree-sitter/parse-action@v4 50 | with: 51 | files: | 52 | examples/**/*.ql 53 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - grammar.js 8 | pull_request: 9 | paths: 10 | - grammar.js 11 | 12 | jobs: 13 | lint: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v4 18 | - name: Set up Node.js 19 | uses: actions/setup-node@v4 20 | with: 21 | cache: npm 22 | node-version: ${{vars.NODE_VERSION}} 23 | - name: Install modules 24 | run: npm ci --legacy-peer-deps 25 | - name: Run ESLint 26 | run: npm run lint 27 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish packages 2 | 3 | on: 4 | push: 5 | tags: ["*"] 6 | 7 | permissions: 8 | contents: write 9 | id-token: write 10 | attestations: write 11 | 12 | jobs: 13 | github: 14 | uses: tree-sitter/workflows/.github/workflows/release.yml@main 15 | with: 16 | generate: true 17 | attestations: true 18 | npm: 19 | uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main 20 | secrets: 21 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 22 | with: 23 | generate: true 24 | crates: 25 | uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main 26 | secrets: 27 | CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_REGISTRY_TOKEN}} 28 | with: 29 | generate: true 30 | pypi: 31 | uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main 32 | secrets: 33 | PYPI_API_TOKEN: ${{secrets.PYPI_API_TOKEN}} 34 | with: 35 | generate: true 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Rust artifacts 2 | target/ 3 | 4 | # Node artifacts 5 | build/ 6 | prebuilds/ 7 | node_modules/ 8 | 9 | # Swift artifacts 10 | .build/ 11 | 12 | # Go artifacts 13 | _obj/ 14 | 15 | # Python artifacts 16 | .venv/ 17 | dist/ 18 | *.egg-info 19 | *.whl 20 | 21 | # C artifacts 22 | *.a 23 | *.so 24 | *.so.* 25 | *.dylib 26 | *.dll 27 | *.pc 28 | 29 | # Example dirs 30 | /examples/*/ 31 | 32 | # Grammar volatiles 33 | *.wasm 34 | *.obj 35 | *.o 36 | 37 | # Archives 38 | *.tar.gz 39 | *.tgz 40 | *.zip 41 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | project(tree-sitter-ql 4 | VERSION "0.23.1" 5 | DESCRIPTION "Semmle QL grammar for tree-sitter" 6 | HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-ql" 7 | LANGUAGES C) 8 | 9 | option(BUILD_SHARED_LIBS "Build using shared libraries" ON) 10 | option(TREE_SITTER_REUSE_ALLOCATOR "Reuse the library allocator" OFF) 11 | 12 | set(TREE_SITTER_ABI_VERSION 14 CACHE STRING "Tree-sitter ABI version") 13 | if(NOT ${TREE_SITTER_ABI_VERSION} MATCHES "^[0-9]+$") 14 | unset(TREE_SITTER_ABI_VERSION CACHE) 15 | message(FATAL_ERROR "TREE_SITTER_ABI_VERSION must be an integer") 16 | endif() 17 | 18 | find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI") 19 | 20 | add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" 21 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" 22 | COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json 23 | --abi=${TREE_SITTER_ABI_VERSION} 24 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 25 | COMMENT "Generating parser.c") 26 | 27 | add_library(tree-sitter-ql src/parser.c) 28 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c) 29 | target_sources(tree-sitter-ql PRIVATE src/scanner.c) 30 | endif() 31 | target_include_directories(tree-sitter-ql PRIVATE src) 32 | 33 | target_compile_definitions(tree-sitter-ql PRIVATE 34 | $<$:TREE_SITTER_REUSE_ALLOCATOR> 35 | $<$:TREE_SITTER_DEBUG>) 36 | 37 | set_target_properties(tree-sitter-ql 38 | PROPERTIES 39 | C_STANDARD 11 40 | POSITION_INDEPENDENT_CODE ON 41 | SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}" 42 | DEFINE_SYMBOL "") 43 | 44 | configure_file(bindings/c/tree-sitter-ql.pc.in 45 | "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-ql.pc" @ONLY) 46 | 47 | include(GNUInstallDirs) 48 | 49 | install(FILES bindings/c/tree-sitter-ql.h 50 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tree_sitter") 51 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-ql.pc" 52 | DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig") 53 | install(TARGETS tree-sitter-ql 54 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 55 | 56 | add_custom_target(ts-test "${TREE_SITTER_CLI}" test 57 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 58 | COMMENT "tree-sitter test") 59 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "cc" 16 | version = "1.1.37" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" 19 | dependencies = [ 20 | "shlex", 21 | ] 22 | 23 | [[package]] 24 | name = "memchr" 25 | version = "2.7.4" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 28 | 29 | [[package]] 30 | name = "regex" 31 | version = "1.11.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 34 | dependencies = [ 35 | "aho-corasick", 36 | "memchr", 37 | "regex-automata", 38 | "regex-syntax", 39 | ] 40 | 41 | [[package]] 42 | name = "regex-automata" 43 | version = "0.4.8" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" 46 | dependencies = [ 47 | "aho-corasick", 48 | "memchr", 49 | "regex-syntax", 50 | ] 51 | 52 | [[package]] 53 | name = "regex-syntax" 54 | version = "0.8.5" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 57 | 58 | [[package]] 59 | name = "shlex" 60 | version = "1.3.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 63 | 64 | [[package]] 65 | name = "streaming-iterator" 66 | version = "0.1.9" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" 69 | 70 | [[package]] 71 | name = "tree-sitter" 72 | version = "0.24.4" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "b67baf55e7e1b6806063b1e51041069c90afff16afcbbccd278d899f9d84bca4" 75 | dependencies = [ 76 | "cc", 77 | "regex", 78 | "regex-syntax", 79 | "streaming-iterator", 80 | "tree-sitter-language", 81 | ] 82 | 83 | [[package]] 84 | name = "tree-sitter-language" 85 | version = "0.1.2" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "e8ddffe35a0e5eeeadf13ff7350af564c6e73993a24db62caee1822b185c2600" 88 | 89 | [[package]] 90 | name = "tree-sitter-ql" 91 | version = "0.23.1" 92 | dependencies = [ 93 | "cc", 94 | "tree-sitter", 95 | "tree-sitter-language", 96 | ] 97 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-ql" 3 | description = "Semmle QL grammar for tree-sitter" 4 | version = "0.23.1" 5 | authors = ["Sam Lanning "] 6 | license = "MIT" 7 | readme = "README.md" 8 | keywords = ["incremental", "parsing", "tree-sitter", "ql"] 9 | categories = ["parsing", "text-editors"] 10 | repository = "https://github.com/tree-sitter/tree-sitter-ql" 11 | edition = "2021" 12 | autoexamples = false 13 | 14 | build = "bindings/rust/build.rs" 15 | include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*", "tree-sitter.json"] 16 | 17 | [lib] 18 | path = "bindings/rust/lib.rs" 19 | 20 | [dependencies] 21 | tree-sitter-language = "0.1" 22 | 23 | [build-dependencies] 24 | cc = "1.1" 25 | 26 | [dev-dependencies] 27 | tree-sitter = "0.24" 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2024 GitHub, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | $(error Windows is not supported) 3 | endif 4 | 5 | LANGUAGE_NAME := tree-sitter-ql 6 | HOMEPAGE_URL := https://github.com/tree-sitter/tree-sitter-ql 7 | VERSION := 0.23.1 8 | 9 | # repository 10 | SRC_DIR := src 11 | 12 | TS ?= tree-sitter 13 | 14 | # install directory layout 15 | PREFIX ?= /usr/local 16 | INCLUDEDIR ?= $(PREFIX)/include 17 | LIBDIR ?= $(PREFIX)/lib 18 | PCLIBDIR ?= $(LIBDIR)/pkgconfig 19 | 20 | # source/object files 21 | PARSER := $(SRC_DIR)/parser.c 22 | EXTRAS := $(filter-out $(PARSER),$(wildcard $(SRC_DIR)/*.c)) 23 | OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS)) 24 | 25 | # flags 26 | ARFLAGS ?= rcs 27 | override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC 28 | 29 | # ABI versioning 30 | SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER)) 31 | SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION))) 32 | 33 | # OS-specific bits 34 | ifeq ($(shell uname),Darwin) 35 | SOEXT = dylib 36 | SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT) 37 | SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT) 38 | LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks 39 | else 40 | SOEXT = so 41 | SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR) 42 | SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR) 43 | LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER) 44 | endif 45 | ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),) 46 | PCLIBDIR := $(PREFIX)/libdata/pkgconfig 47 | endif 48 | 49 | all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc 50 | 51 | lib$(LANGUAGE_NAME).a: $(OBJS) 52 | $(AR) $(ARFLAGS) $@ $^ 53 | 54 | lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS) 55 | $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@ 56 | ifneq ($(STRIP),) 57 | $(STRIP) $@ 58 | endif 59 | 60 | $(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in 61 | sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \ 62 | -e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \ 63 | -e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \ 64 | -e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \ 65 | -e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \ 66 | -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@ 67 | 68 | $(PARSER): $(SRC_DIR)/grammar.json 69 | $(TS) generate $^ 70 | 71 | install: all 72 | install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' 73 | install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h 74 | install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 75 | install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a 76 | install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) 77 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) 78 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) 79 | 80 | uninstall: 81 | $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \ 82 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \ 83 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \ 84 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \ 85 | '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \ 86 | '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 87 | 88 | clean: 89 | $(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) 90 | 91 | test: 92 | $(TS) test 93 | 94 | .PHONY: all install uninstall clean test 95 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "SwiftTreeSitter", 6 | "repositoryURL": "https://github.com/ChimeHQ/SwiftTreeSitter", 7 | "state": { 8 | "branch": null, 9 | "revision": "2599e95310b3159641469d8a21baf2d3d200e61f", 10 | "version": "0.8.0" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "TreeSitterQL", 6 | products: [ 7 | .library(name: "TreeSitterQL", targets: ["TreeSitterQL"]), 8 | ], 9 | dependencies: [ 10 | .package(url: "https://github.com/ChimeHQ/SwiftTreeSitter", from: "0.8.0"), 11 | ], 12 | targets: [ 13 | .target( 14 | name: "TreeSitterQL", 15 | dependencies: [], 16 | path: ".", 17 | sources: [ 18 | "src/parser.c", 19 | ], 20 | resources: [ 21 | .copy("queries") 22 | ], 23 | publicHeadersPath: "bindings/swift", 24 | cSettings: [.headerSearchPath("src")] 25 | ), 26 | .testTarget( 27 | name: "TreeSitterQLTests", 28 | dependencies: [ 29 | "SwiftTreeSitter", 30 | "TreeSitterQL", 31 | ], 32 | path: "bindings/swift/TreeSitterQLTests" 33 | ) 34 | ], 35 | cLanguageStandard: .c11 36 | ) 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-ql 2 | 3 | [![CI][ci]](https://github.com/tree-sitter/tree-sitter-ql/actions/workflows/ci.yml) 4 | [![discord][discord]](https://discord.gg/w7nTvsVJhm) 5 | [![matrix][matrix]](https://matrix.to/#/#tree-sitter-chat:matrix.org) 6 | [![crates][crates]](https://crates.io/crates/tree-sitter-ql) 7 | [![npm][npm]](https://www.npmjs.com/package/tree-sitter-ql) 8 | [![pypi][pypi]](https://pypi.org/project/tree-sitter-ql/) 9 | 10 | tree-sitter grammar for GitHub CodeQL ([Language Spec](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/)) 11 | 12 | [ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter/tree-sitter-ql/ci.yml?logo=github&label=CI 13 | [discord]: https://img.shields.io/discord/1063097320771698699?logo=discord&label=discord 14 | [matrix]: https://img.shields.io/matrix/tree-sitter-chat%3Amatrix.org?logo=matrix&label=matrix 15 | [npm]: https://img.shields.io/npm/v/tree-sitter-ql?logo=npm 16 | [crates]: https://img.shields.io/crates/v/tree-sitter-ql?logo=rust 17 | [pypi]: https://img.shields.io/pypi/v/tree-sitter-ql?logo=pypi&logoColor=ffd242 18 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_ql_binding", 5 | "dependencies": [ 6 | " 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_ql(); 6 | 7 | // "tree-sitter", "language" hashed with BLAKE2 8 | const napi_type_tag LANGUAGE_TYPE_TAG = { 9 | 0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16 10 | }; 11 | 12 | Napi::Object Init(Napi::Env env, Napi::Object exports) { 13 | exports["name"] = Napi::String::New(env, "ql"); 14 | auto language = Napi::External::New(env, tree_sitter_ql()); 15 | language.TypeTag(&LANGUAGE_TYPE_TAG); 16 | exports["language"] = language; 17 | return exports; 18 | } 19 | 20 | NODE_API_MODULE(tree_sitter_ql_binding, Init) 21 | -------------------------------------------------------------------------------- /bindings/node/binding_test.js: -------------------------------------------------------------------------------- 1 | const assert = require("node:assert"); 2 | const { test } = require("node:test"); 3 | 4 | const Parser = require("tree-sitter"); 5 | 6 | test("can load grammar", () => { 7 | const parser = new Parser(); 8 | assert.doesNotThrow(() => parser.setLanguage(require("."))); 9 | }); 10 | -------------------------------------------------------------------------------- /bindings/node/index.d.ts: -------------------------------------------------------------------------------- 1 | type BaseNode = { 2 | type: string; 3 | named: boolean; 4 | }; 5 | 6 | type ChildNode = { 7 | multiple: boolean; 8 | required: boolean; 9 | types: BaseNode[]; 10 | }; 11 | 12 | type NodeInfo = 13 | | (BaseNode & { 14 | subtypes: BaseNode[]; 15 | }) 16 | | (BaseNode & { 17 | fields: { [name: string]: ChildNode }; 18 | children: ChildNode[]; 19 | }); 20 | 21 | type Language = { 22 | name: string; 23 | language: unknown; 24 | nodeTypeInfo: NodeInfo[]; 25 | }; 26 | 27 | declare const language: Language; 28 | export = language; 29 | -------------------------------------------------------------------------------- /bindings/node/index.js: -------------------------------------------------------------------------------- 1 | const root = require("path").join(__dirname, "..", ".."); 2 | 3 | module.exports = 4 | typeof process.versions.bun === "string" 5 | // Support `bun build --compile` by being statically analyzable enough to find the .node file at build-time 6 | ? require(`../../prebuilds/${process.platform}-${process.arch}/tree-sitter-ql.node`) 7 | : require("node-gyp-build")(root); 8 | 9 | try { 10 | module.exports.nodeTypeInfo = require("../../src/node-types.json"); 11 | } catch (_) {} 12 | -------------------------------------------------------------------------------- /bindings/python/tests/test_binding.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import tree_sitter, tree_sitter_ql 4 | 5 | 6 | class TestLanguage(TestCase): 7 | def test_can_load_grammar(self): 8 | try: 9 | tree_sitter.Language(tree_sitter_ql.language()) 10 | except Exception: 11 | self.fail("Error loading QL grammar") 12 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_ql/__init__.py: -------------------------------------------------------------------------------- 1 | """Semmle QL grammar for tree-sitter""" 2 | 3 | from importlib.resources import files as _files 4 | 5 | from ._binding import language 6 | 7 | 8 | def _get_query(name, file): 9 | query = _files(f"{__package__}.queries") / file 10 | globals()[name] = query.read_text() 11 | return globals()[name] 12 | 13 | 14 | def __getattr__(name): 15 | if name == "HIGHLIGHTS_QUERY": 16 | return _get_query("HIGHLIGHTS_QUERY", "highlights.scm") 17 | if name == "TAGS_QUERY": 18 | return _get_query("TAGS_QUERY", "tags.scm") 19 | 20 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 21 | 22 | 23 | __all__ = [ 24 | "language", 25 | "HIGHLIGHTS_QUERY", 26 | "TAGS_QUERY", 27 | ] 28 | 29 | 30 | def __dir__(): 31 | return sorted(__all__ + [ 32 | "__all__", "__builtins__", "__cached__", "__doc__", "__file__", 33 | "__loader__", "__name__", "__package__", "__path__", "__spec__", 34 | ]) 35 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_ql/__init__.pyi: -------------------------------------------------------------------------------- 1 | from typing import Final 2 | 3 | HIGHLIGHTS_QUERY: Final[str] 4 | TAGS_QUERY: Final[str] 5 | 6 | def language() -> object: ... 7 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_ql/binding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_ql(void); 6 | 7 | static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 8 | return PyCapsule_New(tree_sitter_ql(), "tree_sitter.Language", NULL); 9 | } 10 | 11 | static PyMethodDef methods[] = { 12 | {"language", _binding_language, METH_NOARGS, 13 | "Get the tree-sitter language for this grammar."}, 14 | {NULL, NULL, 0, NULL} 15 | }; 16 | 17 | static struct PyModuleDef module = { 18 | .m_base = PyModuleDef_HEAD_INIT, 19 | .m_name = "_binding", 20 | .m_doc = NULL, 21 | .m_size = -1, 22 | .m_methods = methods 23 | }; 24 | 25 | PyMODINIT_FUNC PyInit__binding(void) { 26 | return PyModule_Create(&module); 27 | } 28 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_ql/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tree-sitter/tree-sitter-ql/1fd627a4e8bff8c24c11987474bd33112bead857/bindings/python/tree_sitter_ql/py.typed -------------------------------------------------------------------------------- /bindings/rust/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let src_dir = std::path::Path::new("src"); 3 | 4 | let mut c_config = cc::Build::new(); 5 | c_config.std("c11").include(src_dir); 6 | 7 | #[cfg(target_env = "msvc")] 8 | c_config.flag("-utf-8"); 9 | 10 | let parser_path = src_dir.join("parser.c"); 11 | c_config.file(&parser_path); 12 | println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); 13 | 14 | c_config.compile("tree-sitter-ql"); 15 | } 16 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides QL language support for the [tree-sitter][] parsing library. 2 | //! 3 | //! Typically, you will use the [LANGUAGE][] constant to add this language to a 4 | //! tree-sitter [Parser][], and then use the parser to parse some code: 5 | //! 6 | //! ``` 7 | //! let code = r#" 8 | //! select "hello world" 9 | //! "#; 10 | //! let mut parser = tree_sitter::Parser::new(); 11 | //! let language = tree_sitter_ql::LANGUAGE; 12 | //! parser 13 | //! .set_language(&language.into()) 14 | //! .expect("Error loading QL parser"); 15 | //! let tree = parser.parse(code, None).unwrap(); 16 | //! assert!(!tree.root_node().has_error()); 17 | //! ``` 18 | //! 19 | //! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html 20 | //! [tree-sitter]: https://tree-sitter.github.io/ 21 | 22 | use tree_sitter_language::LanguageFn; 23 | 24 | extern "C" { 25 | fn tree_sitter_ql() -> *const (); 26 | } 27 | 28 | /// The tree-sitter [`LanguageFn`][LanguageFn] for this grammar. 29 | /// 30 | /// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html 31 | pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_ql) }; 32 | 33 | /// The content of the [`node-types.json`][] file for this grammar. 34 | /// 35 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types 36 | pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); 37 | 38 | /// The syntax highlighting query for this language. 39 | pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); 40 | 41 | /// The symbol tagging query for this language. 42 | pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); 43 | 44 | #[cfg(test)] 45 | mod tests { 46 | #[test] 47 | fn test_can_load_grammar() { 48 | let mut parser = tree_sitter::Parser::new(); 49 | parser 50 | .set_language(&super::LANGUAGE.into()) 51 | .expect("Error loading QL parser"); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterQL/ql.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_QL_H_ 2 | #define TREE_SITTER_QL_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_ql(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_QL_H_ 17 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterQLTests/TreeSitterQLTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftTreeSitter 3 | import TreeSitterQL 4 | 5 | final class TreeSitterQLTests: XCTestCase { 6 | func testCanLoadGrammar() throws { 7 | let parser = Parser() 8 | let language = Language(language: tree_sitter_ql()) 9 | XCTAssertNoThrow(try parser.setLanguage(language), 10 | "Error loading QL grammar") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import treesitter from 'eslint-config-treesitter'; 2 | 3 | export default [ 4 | ...treesitter, 5 | ]; 6 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tree-sitter/tree-sitter-ql 2 | 3 | go 1.22 4 | 5 | require github.com/tree-sitter/go-tree-sitter v0.24.0 6 | 7 | require github.com/mattn/go-pointer v0.0.1 // indirect 8 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= 4 | github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 8 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 9 | github.com/tree-sitter/go-tree-sitter v0.24.0 h1:kRZb6aBNfcI/u0Qh8XEt3zjNVnmxTisDBN+kXK0xRYQ= 10 | github.com/tree-sitter/go-tree-sitter v0.24.0/go.mod h1:x681iFVoLMEwOSIHA1chaLkXlroXEN7WY+VHGFaoDbk= 11 | github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb h1:A8425heRM8mylnv4H58FPUiH+aYivyitre0PzxrfmWs= 12 | github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb/go.mod h1:dOF6gtQiF9UwNh995T5OphYmtIypkjsp3ap7r9AN/iA= 13 | github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148 h1:AfFPZwtwGN01BW1jDdqBVqscTwetvMpydqYZz57RSlc= 14 | github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148/go.mod h1:Bh6U3viD57rFXRYIQ+kmiYtr+1Bx0AceypDLJJSyi9s= 15 | github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33 h1:TwqSV3qLp3tKSqirGLRHnjFk9Tc2oy57LIl+FQ4GjI4= 16 | github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33/go.mod h1:CvCKCt3v04Ufos1zZnNCelBDeCGRpPucaN8QczoUsN4= 17 | github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012 h1:Xvxck3tE5FW7F7bTS97iNM2ADMyCMJztVqn5HYKdJGo= 18 | github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012/go.mod h1:T40D0O1cPvUU/+AmiXVXy1cncYQT6wem4Z0g4SfAYvY= 19 | github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0 h1:c46K6uh5Dz00zJeU9BfjXdb8I+E4RkUdfnWJpQADXFo= 20 | github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0/go.mod h1:hcNt/kOJHcIcuMvouE7LJcYdeFUFbVpBJ6d4wmOA+tU= 21 | github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495 h1:jrt4qbJVEFs4H93/ITxygHc6u0TGqAkkate7TQ4wFSA= 22 | github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495/go.mod h1:oyaR7fLnRV0hT9z6qwE9GkaeTom/hTDwK3H2idcOJFc= 23 | github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5 h1:om4X9AVg3asL8gxNJDcz4e/Wp+VpQj1PY3uJXKr6EOg= 24 | github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5/go.mod h1:nNqgPoV/h9uYWk6kYEFdEAhNVOacpfpRW5SFmdaP4tU= 25 | github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5 h1:pfV3G3k7NCKqKk8THBmyuh2zA33lgYHS3GVrzRR8ry4= 26 | github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5/go.mod h1:GbMKRjLfk0H+PI7nLi1Sx5lHf5wCpLz9al8tQYSxpEk= 27 | github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1 h1:ZXZMDwE+IhUtGug4Brv6NjJWUU3rfkZBKpemf6RY8/g= 28 | github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1/go.mod h1:UKCLuYnJ312Mei+3cyTmGOHzn0YAnaPRECgJmHtzrqs= 29 | github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb h1:EXEM82lFM7JjJb6qiKZXkpIDaCcbV2obNn82ghwj9lw= 30 | github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb/go.mod h1:lXCF1nGG5Dr4J3BTS0ObN4xJCCICiSu/b+Xe/VqMV7g= 31 | github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d h1:fcYCvoXdcP1uRQYXqJHRy6Hec+uKScQdKVtMwK9JeCI= 32 | github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d/go.mod h1:T1nShQ4v5AJtozZ8YyAS4uzUtDAJj/iv4YfwXSbUHzg= 33 | github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447 h1:o9alBu1J/WjrcTKEthYtXmdkDc5OVXD+PqlvnEZ0Lzc= 34 | github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447/go.mod h1:1Oh95COkkTn6Ezp0vcMbvfhRP5gLeqqljR0BYnBzWvc= 35 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 36 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 37 | -------------------------------------------------------------------------------- /grammar.js: -------------------------------------------------------------------------------- 1 | module.exports = grammar({ 2 | name: 'ql', 3 | 4 | conflicts: $ => [ 5 | [$.simpleId, $.className], 6 | [$.simpleId, $.literalId], 7 | [$.moduleName, $.varName], 8 | ], 9 | 10 | extras: $ => [ 11 | /[ \t\r\n]/, 12 | $.line_comment, 13 | $.block_comment, 14 | ], 15 | 16 | word: $ => $._lower_id, 17 | 18 | rules: { 19 | ql: $ => repeat($.moduleMember), 20 | 21 | module: $ => seq( 22 | 'module', 23 | field('name', $.moduleName), 24 | optional( 25 | seq( 26 | '<', 27 | sep1(field('parameter', $.moduleParam), ','), 28 | '>', 29 | ), 30 | ), 31 | optional(seq( 32 | 'implements', 33 | sep1(field('implements', $.signatureExpr), ','), 34 | )), 35 | choice( 36 | seq( 37 | '{', 38 | repeat($.moduleMember), 39 | '}', 40 | ), 41 | $.moduleAliasBody, 42 | ), 43 | ), 44 | 45 | moduleMember: $ => choice( 46 | seq( 47 | repeat($.annotation), 48 | choice($.importDirective, $.classlessPredicate, $.dataclass, $.datatype, $.select, $.module), 49 | ), 50 | $.qldoc, 51 | ), 52 | 53 | importDirective: $ => seq( 54 | 'import', 55 | $.importModuleExpr, 56 | optional(seq('as', $.moduleName)), 57 | ), 58 | 59 | moduleAliasBody: $ => seq('=', $.moduleExpr, ';'), 60 | predicateAliasBody: $ => seq('=', $.predicateExpr, ';'), 61 | typeAliasBody: $ => seq('=', $.typeExpr, ';'), 62 | typeUnionBody: $ => seq('=', $.typeExpr, 'or', sep($.typeExpr, 'or'), ';'), 63 | 64 | classlessPredicate: $ => seq( 65 | field('returnType', choice($.predicate, $.typeExpr)), 66 | field('name', $.predicateName), 67 | choice( 68 | seq('(', sep($.varDecl, ','), ')', $._optbody), 69 | $.predicateAliasBody, 70 | ), 71 | ), 72 | 73 | datatype: $ => seq( 74 | 'newtype', 75 | field('name', $.className), 76 | '=', 77 | $.datatypeBranches, 78 | ), 79 | 80 | datatypeBranches: $ => sep1($.datatypeBranch, 'or'), 81 | 82 | datatypeBranch: $ => seq( 83 | optional($.qldoc), 84 | optional($.annotation), 85 | field('name', $.className), 86 | '(', 87 | sep($.varDecl, ','), 88 | ')', 89 | optional($.body), 90 | ), 91 | 92 | select: $ => seq( 93 | optional(seq('from', sep($.varDecl, ','))), 94 | optional(seq('where', $._exprOrTerm)), 95 | seq('select', $.asExprs, optional($.orderBys)), 96 | ), 97 | 98 | dataclass: $ => seq( 99 | 'class', 100 | field('name', $.className), 101 | choice( 102 | seq( 103 | optional(field('extends', seq('extends', sep1($.typeExpr, ',')))), 104 | optional(field('instanceof', seq('instanceof', sep1($.typeExpr, ',')))), 105 | choice( 106 | seq( 107 | '{', 108 | repeat($.classMember), 109 | '}', 110 | ), 111 | ';', 112 | ), 113 | ), 114 | $.typeAliasBody, 115 | $.typeUnionBody, 116 | ), 117 | ), 118 | 119 | classMember: $ => choice( 120 | seq( 121 | repeat($.annotation), 122 | choice($.charpred, $.memberPredicate, $.field), 123 | ), 124 | $.qldoc, 125 | ), 126 | 127 | charpred: $ => seq($.className, '(', ')', '{', field('body', $._exprOrTerm), '}'), 128 | 129 | memberPredicate: $ => seq( 130 | field('returnType', choice($.predicate, $.typeExpr)), 131 | field('name', $.predicateName), 132 | '(', 133 | sep($.varDecl, ','), 134 | ')', 135 | $._optbody, 136 | ), 137 | 138 | field: $ => seq($.varDecl, ';'), 139 | 140 | _optbody: $ => choice( 141 | $.empty, 142 | $.body, 143 | $.higherOrderTerm, 144 | ), 145 | 146 | empty: _ => ';', 147 | 148 | body: $ => seq('{', $._exprOrTerm, '}'), 149 | 150 | higherOrderTerm: $ => seq( 151 | '=', 152 | field('name', $.literalId), 153 | '(', 154 | sep($.predicateExpr, ','), 155 | ')', 156 | '(', 157 | sep($._call_arg, ','), 158 | ')', 159 | ), 160 | 161 | special_call: $ => seq($.specialId, '(', ')'), 162 | prefix_cast: $ => prec.dynamic(10, seq('(', $.typeExpr, ')', $._exprOrTerm)), 163 | unary_expr: $ => prec.left(9, seq($.unop, $._exprOrTerm)), 164 | mul_expr: $ => prec.left(9, seq( 165 | field('left', $._exprOrTerm), 166 | $.mulop, 167 | field('right', $._exprOrTerm), 168 | )), 169 | add_expr: $ => prec.left(8, seq( 170 | field('left', $._exprOrTerm), 171 | $.addop, 172 | field('right', $._exprOrTerm), 173 | )), 174 | in_expr: $ => prec.left(7, seq( 175 | field('left', $._exprOrTerm), 176 | 'in', 177 | field('right', $._primary), 178 | )), 179 | comp_term: $ => prec.left(6, seq( 180 | field('left', $._exprOrTerm), 181 | $.compop, 182 | field('right', $._exprOrTerm), 183 | )), 184 | instance_of: $ => prec.left(5, seq($._exprOrTerm, 'instanceof', $.typeExpr)), 185 | negation: $ => prec.left(4, seq('not', $._exprOrTerm)), 186 | if_term: $ => prec.left(3, seq( 187 | 'if', field('cond', $._exprOrTerm), 188 | 'then', field('first', $._exprOrTerm), 189 | 'else', field('second', $._exprOrTerm), 190 | )), 191 | conjunction: $ => prec.left(3, seq( 192 | field('left', $._exprOrTerm), 193 | 'and', 194 | field('right', $._exprOrTerm), 195 | )), 196 | disjunction: $ => prec.left(2, seq( 197 | field('left', $._exprOrTerm), 198 | 'or', 199 | field('right', $._exprOrTerm), 200 | )), 201 | implication: $ => prec.left(1, seq( 202 | field('left', $._exprOrTerm), 203 | 'implies', 204 | field('right', $._exprOrTerm), 205 | )), 206 | 207 | quantified: $ => seq($.quantifier, '(', 208 | choice( 209 | seq( 210 | sep($.varDecl, ','), 211 | optional(seq('|', field('range', $._exprOrTerm), optional(seq('|', field('formula', $._exprOrTerm))))), 212 | ), 213 | field('expr', $._exprOrTerm), 214 | ), 215 | ')'), 216 | 217 | specialId: _ => 'none', 218 | 219 | quantifier: _ => choice('exists', 'forall', 'forex'), 220 | 221 | _call_arg: $ => choice( 222 | $._exprOrTerm, // ExprArg 223 | $.underscore, // DontCare 224 | ), 225 | 226 | underscore: _ => '_', 227 | 228 | qualifiedRhs: $ => choice( 229 | seq( // QualCall 230 | field('name', $.predicateName), 231 | optional($.closure), 232 | '(', 233 | sep($._call_arg, ','), 234 | ')', 235 | ), 236 | seq( // QualCast 237 | '(', 238 | $.typeExpr, 239 | ')', 240 | ), 241 | ), 242 | 243 | call_body: $ => seq('(', sep($._call_arg, ','), ')'), 244 | unqual_agg_body: $ => seq( 245 | '(', 246 | sep($.varDecl, ','), 247 | '|', 248 | field('guard', optional($._exprOrTerm)), 249 | field('asExprs', optional(seq('|', $.asExprs))), 250 | ')', 251 | ), 252 | 253 | _call_or_unqual_agg_body: $ => choice($.call_body, $.unqual_agg_body), 254 | 255 | call_or_unqual_agg_expr: $ => prec.dynamic(10, seq($.aritylessPredicateExpr, optional($.closure), $._call_or_unqual_agg_body)), 256 | qualified_expr: $ => seq($._primary, '.', $.qualifiedRhs), 257 | super_ref: $ => seq(optional(seq($.typeExpr, '.')), $.super), 258 | 259 | 260 | // The split here is to ensure that the node is non-empty 261 | full_aggregate_body: $ => choice( 262 | seq(sep($.varDecl, ','), 263 | seq( 264 | '|', 265 | field('guard', optional($._exprOrTerm)), 266 | optional(seq('|', field('asExprs', $.asExprs), field('orderBys', optional($.orderBys)))), 267 | ), 268 | ), 269 | sep1($.varDecl, ','), 270 | ), 271 | 272 | expr_aggregate_body: $ => seq(field('asExprs', $.asExprs), field('orderBys', optional($.orderBys))), 273 | 274 | aggregate: $ => seq($.aggId, // Agg 275 | optional( 276 | seq('[', sep1($._exprOrTerm, ','), ']'), 277 | ), 278 | '(', 279 | optional( 280 | choice($.full_aggregate_body, $.expr_aggregate_body), 281 | ), 282 | ')', 283 | ), 284 | range: $ => seq( // Range 285 | '[', 286 | field('lower', $._exprOrTerm), '..', field('upper', $._exprOrTerm), 287 | ']', 288 | ), 289 | set_literal: $ => seq( 290 | '[', 291 | sep($._exprOrTerm, ','), 292 | optional(','), 293 | ']', 294 | ), 295 | 296 | par_expr: $ => seq('(', $._exprOrTerm, ')'), 297 | 298 | expr_annotation: $ => seq( 299 | field('name', $.annotName), 300 | '[', 301 | field('annot_arg', $.annotName), 302 | ']', 303 | '(', 304 | $._exprOrTerm, 305 | ')', 306 | ), 307 | 308 | _exprOrTerm: $ => choice( 309 | $.special_call, 310 | $.prefix_cast, 311 | $._primary, 312 | $.unary_expr, 313 | $.mul_expr, 314 | $.add_expr, 315 | $.in_expr, 316 | $.comp_term, 317 | $.instance_of, 318 | $.negation, 319 | $.if_term, 320 | $.conjunction, 321 | $.disjunction, 322 | $.implication, 323 | $.quantified, // QuantifiedTerm 324 | ), 325 | 326 | _primary: $ => choice( 327 | $.call_or_unqual_agg_expr, // 328 | $.qualified_expr, // QualifiedExpr 329 | $.literal, // Lit 330 | $.variable, // Var 331 | $.super_ref, 332 | $.aggregate, 333 | $.range, 334 | $.set_literal, 335 | $.par_expr, // ParExpr 336 | $.expr_annotation, // ExprAnnotation 337 | ), 338 | 339 | literal: $ => choice( 340 | $.integer, // IntLit 341 | $.float, // FloatLit 342 | $.bool, // BoolLit 343 | $.string, // StringLit 344 | ), 345 | 346 | 347 | bool: $ => choice($.true, $.false), 348 | 349 | variable: $ => choice($.this, $.result, $.varName), 350 | 351 | compop: _ => choice('=', '!=', '<', '>', '<=', '>='), 352 | 353 | unop: _ => choice('+', '-'), 354 | 355 | mulop: _ => choice('*', '/', '%'), 356 | 357 | addop: _ => choice('+', '-'), 358 | 359 | closure: _ => choice('*', '+'), 360 | 361 | direction: _ => choice('asc', 'desc'), 362 | 363 | varDecl: $ => seq($.typeExpr, $.varName), 364 | 365 | moduleParam: $ => seq( 366 | field('signature', $.signatureExpr), 367 | field('parameter', $.simpleId), 368 | ), 369 | 370 | asExprs: $ => sep1($.asExpr, ','), 371 | 372 | asExpr: $ => seq($._exprOrTerm, optional(seq('as', $.varName))), 373 | 374 | orderBys: $ => seq('order', 'by', sep1($.orderBy, ',')), 375 | 376 | orderBy: $ => seq($._exprOrTerm, optional($.direction)), 377 | 378 | qldoc: _ => /\/\*\*[^*]*\*+([^/*][^*]*\*+)*\//, 379 | 380 | literalId: $ => choice($._lower_id, $._upper_id), 381 | 382 | annotation: $ => choice( 383 | field('name', $.annotName), // SimpleAnnotation 384 | seq( // ArgsAnnotation 385 | field('name', $.annotName), 386 | '[', 387 | field('args', sep1($.annotArg, ',')), 388 | ']', 389 | ), 390 | ), 391 | 392 | annotName: $ => $._lower_id, 393 | 394 | annotArg: $ => choice($.simpleId, $.this, $.result), 395 | 396 | moduleName: $ => $.simpleId, 397 | 398 | importModuleExpr: $ => seq( 399 | repeat(seq(field('qualName', $.simpleId), '.')), 400 | $.moduleExpr, 401 | ), 402 | 403 | moduleExpr: $ => choice( 404 | $.simpleId, 405 | $.moduleInstantiation, 406 | seq($.moduleExpr, '::', field('name', choice($.simpleId, $.moduleInstantiation))), 407 | ), 408 | 409 | moduleInstantiation: $ => seq( 410 | field('name', $.moduleName), 411 | '<', 412 | sep1($.signatureExpr, ','), 413 | '>', 414 | ), 415 | 416 | primitiveType: _ => choice('boolean', 'date', 'float', 'int', 'string'), 417 | 418 | simpleId: $ => choice($._lower_id, $._upper_id), 419 | 420 | className: $ => $._upper_id, 421 | 422 | dbtype: _ => /@[a-z][A-Za-z0-9_]*/, 423 | 424 | typeExpr: $ => choice( 425 | seq(optional(seq(field('qualifier', $.moduleExpr), '::')), field('name', $.className)), 426 | $.dbtype, 427 | $.primitiveType, 428 | ), 429 | 430 | signatureExpr: $ => choice( 431 | field('type_expr', $.typeExpr), 432 | field('mod_expr', $.moduleExpr), 433 | field('predicate', $.predicateExpr), 434 | ), 435 | 436 | predicateName: $ => $._lower_id, 437 | 438 | aritylessPredicateExpr: $ => seq(optional(seq(field('qualifier', $.moduleExpr), '::')), field('name', $.literalId)), 439 | 440 | predicateExpr: $ => seq($.aritylessPredicateExpr, '/', $.integer), 441 | 442 | varName: $ => $.simpleId, 443 | 444 | aggId: _ => choice('avg', 'concat', 'strictconcat', 'count', 'max', 'min', 'rank', 'strictcount', 'strictsum', 'sum', 'any', 'unique'), 445 | 446 | _upper_id: _ => /[A-Z][A-Za-z0-9_]*/, 447 | _lower_id: _ => /[a-z][A-Za-z0-9_]*/, 448 | integer: _ => /[0-9]+/, 449 | float: _ => /[0-9]+\.[0-9]+/, 450 | string: _ => /"([^"\\\r\n\t]|\\["\\nrt])*"/, 451 | line_comment: _ => /\/\/[^\r\n]*/, 452 | block_comment: _ => /\/\*([^*]+\*+([^/*][^*]*\*+)*|\*)\//, 453 | 454 | false: _ => 'false', 455 | predicate: _ => 'predicate', 456 | result: _ => 'result', 457 | super: _ => 'super', 458 | this: _ => 'this', 459 | true: _ => 'true', 460 | }, 461 | }); 462 | 463 | /** 464 | * 465 | * @param {RuleOrLiteral} rule 466 | * @param {string} s 467 | */ 468 | function sep(rule, s) { 469 | return optional(sep1(rule, s)); 470 | } 471 | 472 | /** 473 | * 474 | * @param {RuleOrLiteral} rule 475 | * @param {string} s 476 | */ 477 | function sep1(rule, s) { 478 | return seq(rule, repeat(seq(s, rule))); 479 | } 480 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-ql", 3 | "version": "0.23.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "tree-sitter-ql", 9 | "version": "0.23.1", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "dependencies": { 13 | "node-addon-api": "^8.2.2", 14 | "node-gyp-build": "^4.8.2" 15 | }, 16 | "devDependencies": { 17 | "eslint": "^9.14.0", 18 | "eslint-config-treesitter": "1.0.2", 19 | "prebuildify": "^6.0.1", 20 | "tree-sitter-cli": "^0.24.4" 21 | }, 22 | "peerDependencies": { 23 | "tree-sitter": "^0.21.1" 24 | }, 25 | "peerDependenciesMeta": { 26 | "tree-sitter": { 27 | "optional": true 28 | } 29 | } 30 | }, 31 | "node_modules/@es-joy/jsdoccomment": { 32 | "version": "0.49.0", 33 | "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", 34 | "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", 35 | "dev": true, 36 | "dependencies": { 37 | "comment-parser": "1.4.1", 38 | "esquery": "^1.6.0", 39 | "jsdoc-type-pratt-parser": "~4.1.0" 40 | }, 41 | "engines": { 42 | "node": ">=16" 43 | } 44 | }, 45 | "node_modules/@eslint-community/eslint-utils": { 46 | "version": "4.4.1", 47 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", 48 | "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", 49 | "dev": true, 50 | "dependencies": { 51 | "eslint-visitor-keys": "^3.4.3" 52 | }, 53 | "engines": { 54 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 55 | }, 56 | "funding": { 57 | "url": "https://opencollective.com/eslint" 58 | }, 59 | "peerDependencies": { 60 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 61 | } 62 | }, 63 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 64 | "version": "3.4.3", 65 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 66 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 67 | "dev": true, 68 | "engines": { 69 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 70 | }, 71 | "funding": { 72 | "url": "https://opencollective.com/eslint" 73 | } 74 | }, 75 | "node_modules/@eslint-community/regexpp": { 76 | "version": "4.12.1", 77 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 78 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 79 | "dev": true, 80 | "engines": { 81 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 82 | } 83 | }, 84 | "node_modules/@eslint/config-array": { 85 | "version": "0.18.0", 86 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", 87 | "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", 88 | "dev": true, 89 | "dependencies": { 90 | "@eslint/object-schema": "^2.1.4", 91 | "debug": "^4.3.1", 92 | "minimatch": "^3.1.2" 93 | }, 94 | "engines": { 95 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 96 | } 97 | }, 98 | "node_modules/@eslint/core": { 99 | "version": "0.7.0", 100 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", 101 | "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", 102 | "dev": true, 103 | "engines": { 104 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 105 | } 106 | }, 107 | "node_modules/@eslint/eslintrc": { 108 | "version": "3.1.0", 109 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", 110 | "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", 111 | "dev": true, 112 | "dependencies": { 113 | "ajv": "^6.12.4", 114 | "debug": "^4.3.2", 115 | "espree": "^10.0.1", 116 | "globals": "^14.0.0", 117 | "ignore": "^5.2.0", 118 | "import-fresh": "^3.2.1", 119 | "js-yaml": "^4.1.0", 120 | "minimatch": "^3.1.2", 121 | "strip-json-comments": "^3.1.1" 122 | }, 123 | "engines": { 124 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 125 | }, 126 | "funding": { 127 | "url": "https://opencollective.com/eslint" 128 | } 129 | }, 130 | "node_modules/@eslint/js": { 131 | "version": "9.14.0", 132 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", 133 | "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", 134 | "dev": true, 135 | "engines": { 136 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 137 | } 138 | }, 139 | "node_modules/@eslint/object-schema": { 140 | "version": "2.1.4", 141 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", 142 | "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", 143 | "dev": true, 144 | "engines": { 145 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 146 | } 147 | }, 148 | "node_modules/@eslint/plugin-kit": { 149 | "version": "0.2.2", 150 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", 151 | "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", 152 | "dev": true, 153 | "dependencies": { 154 | "levn": "^0.4.1" 155 | }, 156 | "engines": { 157 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 158 | } 159 | }, 160 | "node_modules/@humanfs/core": { 161 | "version": "0.19.1", 162 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 163 | "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 164 | "dev": true, 165 | "engines": { 166 | "node": ">=18.18.0" 167 | } 168 | }, 169 | "node_modules/@humanfs/node": { 170 | "version": "0.16.6", 171 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", 172 | "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", 173 | "dev": true, 174 | "dependencies": { 175 | "@humanfs/core": "^0.19.1", 176 | "@humanwhocodes/retry": "^0.3.0" 177 | }, 178 | "engines": { 179 | "node": ">=18.18.0" 180 | } 181 | }, 182 | "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { 183 | "version": "0.3.1", 184 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 185 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 186 | "dev": true, 187 | "engines": { 188 | "node": ">=18.18" 189 | }, 190 | "funding": { 191 | "type": "github", 192 | "url": "https://github.com/sponsors/nzakas" 193 | } 194 | }, 195 | "node_modules/@humanwhocodes/module-importer": { 196 | "version": "1.0.1", 197 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 198 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 199 | "dev": true, 200 | "engines": { 201 | "node": ">=12.22" 202 | }, 203 | "funding": { 204 | "type": "github", 205 | "url": "https://github.com/sponsors/nzakas" 206 | } 207 | }, 208 | "node_modules/@humanwhocodes/retry": { 209 | "version": "0.4.1", 210 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", 211 | "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", 212 | "dev": true, 213 | "engines": { 214 | "node": ">=18.18" 215 | }, 216 | "funding": { 217 | "type": "github", 218 | "url": "https://github.com/sponsors/nzakas" 219 | } 220 | }, 221 | "node_modules/@pkgr/core": { 222 | "version": "0.1.1", 223 | "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", 224 | "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", 225 | "dev": true, 226 | "engines": { 227 | "node": "^12.20.0 || ^14.18.0 || >=16.0.0" 228 | }, 229 | "funding": { 230 | "url": "https://opencollective.com/unts" 231 | } 232 | }, 233 | "node_modules/@types/estree": { 234 | "version": "1.0.6", 235 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 236 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 237 | "dev": true 238 | }, 239 | "node_modules/@types/json-schema": { 240 | "version": "7.0.15", 241 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 242 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 243 | "dev": true 244 | }, 245 | "node_modules/acorn": { 246 | "version": "8.14.0", 247 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", 248 | "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", 249 | "dev": true, 250 | "bin": { 251 | "acorn": "bin/acorn" 252 | }, 253 | "engines": { 254 | "node": ">=0.4.0" 255 | } 256 | }, 257 | "node_modules/acorn-jsx": { 258 | "version": "5.3.2", 259 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 260 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 261 | "dev": true, 262 | "peerDependencies": { 263 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 264 | } 265 | }, 266 | "node_modules/ajv": { 267 | "version": "6.12.6", 268 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 269 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 270 | "dev": true, 271 | "dependencies": { 272 | "fast-deep-equal": "^3.1.1", 273 | "fast-json-stable-stringify": "^2.0.0", 274 | "json-schema-traverse": "^0.4.1", 275 | "uri-js": "^4.2.2" 276 | }, 277 | "funding": { 278 | "type": "github", 279 | "url": "https://github.com/sponsors/epoberezkin" 280 | } 281 | }, 282 | "node_modules/ansi-styles": { 283 | "version": "4.3.0", 284 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 285 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 286 | "dev": true, 287 | "dependencies": { 288 | "color-convert": "^2.0.1" 289 | }, 290 | "engines": { 291 | "node": ">=8" 292 | }, 293 | "funding": { 294 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 295 | } 296 | }, 297 | "node_modules/are-docs-informative": { 298 | "version": "0.0.2", 299 | "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", 300 | "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", 301 | "dev": true, 302 | "engines": { 303 | "node": ">=14" 304 | } 305 | }, 306 | "node_modules/argparse": { 307 | "version": "2.0.1", 308 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 309 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 310 | "dev": true 311 | }, 312 | "node_modules/balanced-match": { 313 | "version": "1.0.2", 314 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 315 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 316 | "dev": true 317 | }, 318 | "node_modules/base64-js": { 319 | "version": "1.5.1", 320 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 321 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 322 | "dev": true, 323 | "funding": [ 324 | { 325 | "type": "github", 326 | "url": "https://github.com/sponsors/feross" 327 | }, 328 | { 329 | "type": "patreon", 330 | "url": "https://www.patreon.com/feross" 331 | }, 332 | { 333 | "type": "consulting", 334 | "url": "https://feross.org/support" 335 | } 336 | ] 337 | }, 338 | "node_modules/bl": { 339 | "version": "4.1.0", 340 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", 341 | "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", 342 | "dev": true, 343 | "dependencies": { 344 | "buffer": "^5.5.0", 345 | "inherits": "^2.0.4", 346 | "readable-stream": "^3.4.0" 347 | } 348 | }, 349 | "node_modules/brace-expansion": { 350 | "version": "1.1.11", 351 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 352 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 353 | "dev": true, 354 | "dependencies": { 355 | "balanced-match": "^1.0.0", 356 | "concat-map": "0.0.1" 357 | } 358 | }, 359 | "node_modules/buffer": { 360 | "version": "5.7.1", 361 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 362 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 363 | "dev": true, 364 | "funding": [ 365 | { 366 | "type": "github", 367 | "url": "https://github.com/sponsors/feross" 368 | }, 369 | { 370 | "type": "patreon", 371 | "url": "https://www.patreon.com/feross" 372 | }, 373 | { 374 | "type": "consulting", 375 | "url": "https://feross.org/support" 376 | } 377 | ], 378 | "dependencies": { 379 | "base64-js": "^1.3.1", 380 | "ieee754": "^1.1.13" 381 | } 382 | }, 383 | "node_modules/callsites": { 384 | "version": "3.1.0", 385 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 386 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 387 | "dev": true, 388 | "engines": { 389 | "node": ">=6" 390 | } 391 | }, 392 | "node_modules/chalk": { 393 | "version": "4.1.2", 394 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 395 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 396 | "dev": true, 397 | "dependencies": { 398 | "ansi-styles": "^4.1.0", 399 | "supports-color": "^7.1.0" 400 | }, 401 | "engines": { 402 | "node": ">=10" 403 | }, 404 | "funding": { 405 | "url": "https://github.com/chalk/chalk?sponsor=1" 406 | } 407 | }, 408 | "node_modules/chownr": { 409 | "version": "1.1.4", 410 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 411 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", 412 | "dev": true 413 | }, 414 | "node_modules/color-convert": { 415 | "version": "2.0.1", 416 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 417 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 418 | "dev": true, 419 | "dependencies": { 420 | "color-name": "~1.1.4" 421 | }, 422 | "engines": { 423 | "node": ">=7.0.0" 424 | } 425 | }, 426 | "node_modules/color-name": { 427 | "version": "1.1.4", 428 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 429 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 430 | "dev": true 431 | }, 432 | "node_modules/comment-parser": { 433 | "version": "1.4.1", 434 | "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", 435 | "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", 436 | "dev": true, 437 | "engines": { 438 | "node": ">= 12.0.0" 439 | } 440 | }, 441 | "node_modules/concat-map": { 442 | "version": "0.0.1", 443 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 444 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 445 | "dev": true 446 | }, 447 | "node_modules/cross-spawn": { 448 | "version": "7.0.5", 449 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", 450 | "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", 451 | "dev": true, 452 | "dependencies": { 453 | "path-key": "^3.1.0", 454 | "shebang-command": "^2.0.0", 455 | "which": "^2.0.1" 456 | }, 457 | "engines": { 458 | "node": ">= 8" 459 | } 460 | }, 461 | "node_modules/debug": { 462 | "version": "4.3.7", 463 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", 464 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", 465 | "dev": true, 466 | "dependencies": { 467 | "ms": "^2.1.3" 468 | }, 469 | "engines": { 470 | "node": ">=6.0" 471 | }, 472 | "peerDependenciesMeta": { 473 | "supports-color": { 474 | "optional": true 475 | } 476 | } 477 | }, 478 | "node_modules/deep-is": { 479 | "version": "0.1.4", 480 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 481 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 482 | "dev": true 483 | }, 484 | "node_modules/end-of-stream": { 485 | "version": "1.4.4", 486 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 487 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 488 | "dev": true, 489 | "dependencies": { 490 | "once": "^1.4.0" 491 | } 492 | }, 493 | "node_modules/es-module-lexer": { 494 | "version": "1.5.4", 495 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", 496 | "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", 497 | "dev": true 498 | }, 499 | "node_modules/escape-string-regexp": { 500 | "version": "4.0.0", 501 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 502 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 503 | "dev": true, 504 | "engines": { 505 | "node": ">=10" 506 | }, 507 | "funding": { 508 | "url": "https://github.com/sponsors/sindresorhus" 509 | } 510 | }, 511 | "node_modules/eslint": { 512 | "version": "9.14.0", 513 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", 514 | "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", 515 | "dev": true, 516 | "dependencies": { 517 | "@eslint-community/eslint-utils": "^4.2.0", 518 | "@eslint-community/regexpp": "^4.12.1", 519 | "@eslint/config-array": "^0.18.0", 520 | "@eslint/core": "^0.7.0", 521 | "@eslint/eslintrc": "^3.1.0", 522 | "@eslint/js": "9.14.0", 523 | "@eslint/plugin-kit": "^0.2.0", 524 | "@humanfs/node": "^0.16.6", 525 | "@humanwhocodes/module-importer": "^1.0.1", 526 | "@humanwhocodes/retry": "^0.4.0", 527 | "@types/estree": "^1.0.6", 528 | "@types/json-schema": "^7.0.15", 529 | "ajv": "^6.12.4", 530 | "chalk": "^4.0.0", 531 | "cross-spawn": "^7.0.2", 532 | "debug": "^4.3.2", 533 | "escape-string-regexp": "^4.0.0", 534 | "eslint-scope": "^8.2.0", 535 | "eslint-visitor-keys": "^4.2.0", 536 | "espree": "^10.3.0", 537 | "esquery": "^1.5.0", 538 | "esutils": "^2.0.2", 539 | "fast-deep-equal": "^3.1.3", 540 | "file-entry-cache": "^8.0.0", 541 | "find-up": "^5.0.0", 542 | "glob-parent": "^6.0.2", 543 | "ignore": "^5.2.0", 544 | "imurmurhash": "^0.1.4", 545 | "is-glob": "^4.0.0", 546 | "json-stable-stringify-without-jsonify": "^1.0.1", 547 | "lodash.merge": "^4.6.2", 548 | "minimatch": "^3.1.2", 549 | "natural-compare": "^1.4.0", 550 | "optionator": "^0.9.3", 551 | "text-table": "^0.2.0" 552 | }, 553 | "bin": { 554 | "eslint": "bin/eslint.js" 555 | }, 556 | "engines": { 557 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 558 | }, 559 | "funding": { 560 | "url": "https://eslint.org/donate" 561 | }, 562 | "peerDependencies": { 563 | "jiti": "*" 564 | }, 565 | "peerDependenciesMeta": { 566 | "jiti": { 567 | "optional": true 568 | } 569 | } 570 | }, 571 | "node_modules/eslint-config-treesitter": { 572 | "version": "1.0.2", 573 | "resolved": "https://registry.npmjs.org/eslint-config-treesitter/-/eslint-config-treesitter-1.0.2.tgz", 574 | "integrity": "sha512-OkzjA0oaNgYUFkGmo9T2cvRE7cxzh1dgSt0laO8Hdcypp9di8lebldoPivALXFusRb7s54J5exIw1w7l+g85Rg==", 575 | "dev": true, 576 | "dependencies": { 577 | "eslint-plugin-jsdoc": "^50.2.4" 578 | }, 579 | "peerDependencies": { 580 | "eslint": ">= 9" 581 | } 582 | }, 583 | "node_modules/eslint-plugin-jsdoc": { 584 | "version": "50.4.3", 585 | "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.4.3.tgz", 586 | "integrity": "sha512-uWtwFxGRv6B8sU63HZM5dAGDhgsatb+LONwmILZJhdRALLOkCX2HFZhdL/Kw2ls8SQMAVEfK+LmnEfxInRN8HA==", 587 | "dev": true, 588 | "dependencies": { 589 | "@es-joy/jsdoccomment": "~0.49.0", 590 | "are-docs-informative": "^0.0.2", 591 | "comment-parser": "1.4.1", 592 | "debug": "^4.3.6", 593 | "escape-string-regexp": "^4.0.0", 594 | "espree": "^10.1.0", 595 | "esquery": "^1.6.0", 596 | "parse-imports": "^2.1.1", 597 | "semver": "^7.6.3", 598 | "spdx-expression-parse": "^4.0.0", 599 | "synckit": "^0.9.1" 600 | }, 601 | "engines": { 602 | "node": ">=18" 603 | }, 604 | "peerDependencies": { 605 | "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" 606 | } 607 | }, 608 | "node_modules/eslint-scope": { 609 | "version": "8.2.0", 610 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", 611 | "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", 612 | "dev": true, 613 | "dependencies": { 614 | "esrecurse": "^4.3.0", 615 | "estraverse": "^5.2.0" 616 | }, 617 | "engines": { 618 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 619 | }, 620 | "funding": { 621 | "url": "https://opencollective.com/eslint" 622 | } 623 | }, 624 | "node_modules/eslint-visitor-keys": { 625 | "version": "4.2.0", 626 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", 627 | "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", 628 | "dev": true, 629 | "engines": { 630 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 631 | }, 632 | "funding": { 633 | "url": "https://opencollective.com/eslint" 634 | } 635 | }, 636 | "node_modules/espree": { 637 | "version": "10.3.0", 638 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", 639 | "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", 640 | "dev": true, 641 | "dependencies": { 642 | "acorn": "^8.14.0", 643 | "acorn-jsx": "^5.3.2", 644 | "eslint-visitor-keys": "^4.2.0" 645 | }, 646 | "engines": { 647 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 648 | }, 649 | "funding": { 650 | "url": "https://opencollective.com/eslint" 651 | } 652 | }, 653 | "node_modules/esquery": { 654 | "version": "1.6.0", 655 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 656 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 657 | "dev": true, 658 | "dependencies": { 659 | "estraverse": "^5.1.0" 660 | }, 661 | "engines": { 662 | "node": ">=0.10" 663 | } 664 | }, 665 | "node_modules/esrecurse": { 666 | "version": "4.3.0", 667 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 668 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 669 | "dev": true, 670 | "dependencies": { 671 | "estraverse": "^5.2.0" 672 | }, 673 | "engines": { 674 | "node": ">=4.0" 675 | } 676 | }, 677 | "node_modules/estraverse": { 678 | "version": "5.3.0", 679 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 680 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 681 | "dev": true, 682 | "engines": { 683 | "node": ">=4.0" 684 | } 685 | }, 686 | "node_modules/esutils": { 687 | "version": "2.0.3", 688 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 689 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 690 | "dev": true, 691 | "engines": { 692 | "node": ">=0.10.0" 693 | } 694 | }, 695 | "node_modules/fast-deep-equal": { 696 | "version": "3.1.3", 697 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 698 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 699 | "dev": true 700 | }, 701 | "node_modules/fast-json-stable-stringify": { 702 | "version": "2.1.0", 703 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 704 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 705 | "dev": true 706 | }, 707 | "node_modules/fast-levenshtein": { 708 | "version": "2.0.6", 709 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 710 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 711 | "dev": true 712 | }, 713 | "node_modules/file-entry-cache": { 714 | "version": "8.0.0", 715 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 716 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 717 | "dev": true, 718 | "dependencies": { 719 | "flat-cache": "^4.0.0" 720 | }, 721 | "engines": { 722 | "node": ">=16.0.0" 723 | } 724 | }, 725 | "node_modules/find-up": { 726 | "version": "5.0.0", 727 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 728 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 729 | "dev": true, 730 | "dependencies": { 731 | "locate-path": "^6.0.0", 732 | "path-exists": "^4.0.0" 733 | }, 734 | "engines": { 735 | "node": ">=10" 736 | }, 737 | "funding": { 738 | "url": "https://github.com/sponsors/sindresorhus" 739 | } 740 | }, 741 | "node_modules/flat-cache": { 742 | "version": "4.0.1", 743 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 744 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 745 | "dev": true, 746 | "dependencies": { 747 | "flatted": "^3.2.9", 748 | "keyv": "^4.5.4" 749 | }, 750 | "engines": { 751 | "node": ">=16" 752 | } 753 | }, 754 | "node_modules/flatted": { 755 | "version": "3.3.1", 756 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", 757 | "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", 758 | "dev": true 759 | }, 760 | "node_modules/fs-constants": { 761 | "version": "1.0.0", 762 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 763 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", 764 | "dev": true 765 | }, 766 | "node_modules/glob-parent": { 767 | "version": "6.0.2", 768 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 769 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 770 | "dev": true, 771 | "dependencies": { 772 | "is-glob": "^4.0.3" 773 | }, 774 | "engines": { 775 | "node": ">=10.13.0" 776 | } 777 | }, 778 | "node_modules/globals": { 779 | "version": "14.0.0", 780 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 781 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 782 | "dev": true, 783 | "engines": { 784 | "node": ">=18" 785 | }, 786 | "funding": { 787 | "url": "https://github.com/sponsors/sindresorhus" 788 | } 789 | }, 790 | "node_modules/has-flag": { 791 | "version": "4.0.0", 792 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 793 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 794 | "dev": true, 795 | "engines": { 796 | "node": ">=8" 797 | } 798 | }, 799 | "node_modules/ieee754": { 800 | "version": "1.2.1", 801 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 802 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 803 | "dev": true, 804 | "funding": [ 805 | { 806 | "type": "github", 807 | "url": "https://github.com/sponsors/feross" 808 | }, 809 | { 810 | "type": "patreon", 811 | "url": "https://www.patreon.com/feross" 812 | }, 813 | { 814 | "type": "consulting", 815 | "url": "https://feross.org/support" 816 | } 817 | ] 818 | }, 819 | "node_modules/ignore": { 820 | "version": "5.3.2", 821 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 822 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 823 | "dev": true, 824 | "engines": { 825 | "node": ">= 4" 826 | } 827 | }, 828 | "node_modules/import-fresh": { 829 | "version": "3.3.0", 830 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 831 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 832 | "dev": true, 833 | "dependencies": { 834 | "parent-module": "^1.0.0", 835 | "resolve-from": "^4.0.0" 836 | }, 837 | "engines": { 838 | "node": ">=6" 839 | }, 840 | "funding": { 841 | "url": "https://github.com/sponsors/sindresorhus" 842 | } 843 | }, 844 | "node_modules/imurmurhash": { 845 | "version": "0.1.4", 846 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 847 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 848 | "dev": true, 849 | "engines": { 850 | "node": ">=0.8.19" 851 | } 852 | }, 853 | "node_modules/inherits": { 854 | "version": "2.0.4", 855 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 856 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 857 | "dev": true 858 | }, 859 | "node_modules/is-extglob": { 860 | "version": "2.1.1", 861 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 862 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 863 | "dev": true, 864 | "engines": { 865 | "node": ">=0.10.0" 866 | } 867 | }, 868 | "node_modules/is-glob": { 869 | "version": "4.0.3", 870 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 871 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 872 | "dev": true, 873 | "dependencies": { 874 | "is-extglob": "^2.1.1" 875 | }, 876 | "engines": { 877 | "node": ">=0.10.0" 878 | } 879 | }, 880 | "node_modules/isexe": { 881 | "version": "2.0.0", 882 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 883 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 884 | "dev": true 885 | }, 886 | "node_modules/js-yaml": { 887 | "version": "4.1.0", 888 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 889 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 890 | "dev": true, 891 | "dependencies": { 892 | "argparse": "^2.0.1" 893 | }, 894 | "bin": { 895 | "js-yaml": "bin/js-yaml.js" 896 | } 897 | }, 898 | "node_modules/jsdoc-type-pratt-parser": { 899 | "version": "4.1.0", 900 | "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", 901 | "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", 902 | "dev": true, 903 | "engines": { 904 | "node": ">=12.0.0" 905 | } 906 | }, 907 | "node_modules/json-buffer": { 908 | "version": "3.0.1", 909 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 910 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 911 | "dev": true 912 | }, 913 | "node_modules/json-schema-traverse": { 914 | "version": "0.4.1", 915 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 916 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 917 | "dev": true 918 | }, 919 | "node_modules/json-stable-stringify-without-jsonify": { 920 | "version": "1.0.1", 921 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 922 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 923 | "dev": true 924 | }, 925 | "node_modules/keyv": { 926 | "version": "4.5.4", 927 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 928 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 929 | "dev": true, 930 | "dependencies": { 931 | "json-buffer": "3.0.1" 932 | } 933 | }, 934 | "node_modules/levn": { 935 | "version": "0.4.1", 936 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 937 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 938 | "dev": true, 939 | "dependencies": { 940 | "prelude-ls": "^1.2.1", 941 | "type-check": "~0.4.0" 942 | }, 943 | "engines": { 944 | "node": ">= 0.8.0" 945 | } 946 | }, 947 | "node_modules/locate-path": { 948 | "version": "6.0.0", 949 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 950 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 951 | "dev": true, 952 | "dependencies": { 953 | "p-locate": "^5.0.0" 954 | }, 955 | "engines": { 956 | "node": ">=10" 957 | }, 958 | "funding": { 959 | "url": "https://github.com/sponsors/sindresorhus" 960 | } 961 | }, 962 | "node_modules/lodash.merge": { 963 | "version": "4.6.2", 964 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 965 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 966 | "dev": true 967 | }, 968 | "node_modules/minimatch": { 969 | "version": "3.1.2", 970 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 971 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 972 | "dev": true, 973 | "dependencies": { 974 | "brace-expansion": "^1.1.7" 975 | }, 976 | "engines": { 977 | "node": "*" 978 | } 979 | }, 980 | "node_modules/minimist": { 981 | "version": "1.2.8", 982 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 983 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 984 | "dev": true, 985 | "funding": { 986 | "url": "https://github.com/sponsors/ljharb" 987 | } 988 | }, 989 | "node_modules/mkdirp-classic": { 990 | "version": "0.5.3", 991 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 992 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", 993 | "dev": true 994 | }, 995 | "node_modules/ms": { 996 | "version": "2.1.3", 997 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 998 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 999 | "dev": true 1000 | }, 1001 | "node_modules/natural-compare": { 1002 | "version": "1.4.0", 1003 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1004 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 1005 | "dev": true 1006 | }, 1007 | "node_modules/node-abi": { 1008 | "version": "3.67.0", 1009 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz", 1010 | "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==", 1011 | "dev": true, 1012 | "dependencies": { 1013 | "semver": "^7.3.5" 1014 | }, 1015 | "engines": { 1016 | "node": ">=10" 1017 | } 1018 | }, 1019 | "node_modules/node-addon-api": { 1020 | "version": "8.2.2", 1021 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.2.2.tgz", 1022 | "integrity": "sha512-9emqXAKhVoNrQ792nLI/wpzPpJ/bj/YXxW0CvAau1+RdGBcCRF1Dmz7719zgVsQNrzHl9Tzn3ImZ4qWFarWL0A==", 1023 | "engines": { 1024 | "node": "^18 || ^20 || >= 21" 1025 | } 1026 | }, 1027 | "node_modules/node-gyp-build": { 1028 | "version": "4.8.2", 1029 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", 1030 | "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", 1031 | "bin": { 1032 | "node-gyp-build": "bin.js", 1033 | "node-gyp-build-optional": "optional.js", 1034 | "node-gyp-build-test": "build-test.js" 1035 | } 1036 | }, 1037 | "node_modules/npm-run-path": { 1038 | "version": "3.1.0", 1039 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", 1040 | "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", 1041 | "dev": true, 1042 | "dependencies": { 1043 | "path-key": "^3.0.0" 1044 | }, 1045 | "engines": { 1046 | "node": ">=8" 1047 | } 1048 | }, 1049 | "node_modules/once": { 1050 | "version": "1.4.0", 1051 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1052 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1053 | "dev": true, 1054 | "dependencies": { 1055 | "wrappy": "1" 1056 | } 1057 | }, 1058 | "node_modules/optionator": { 1059 | "version": "0.9.4", 1060 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 1061 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 1062 | "dev": true, 1063 | "dependencies": { 1064 | "deep-is": "^0.1.3", 1065 | "fast-levenshtein": "^2.0.6", 1066 | "levn": "^0.4.1", 1067 | "prelude-ls": "^1.2.1", 1068 | "type-check": "^0.4.0", 1069 | "word-wrap": "^1.2.5" 1070 | }, 1071 | "engines": { 1072 | "node": ">= 0.8.0" 1073 | } 1074 | }, 1075 | "node_modules/p-limit": { 1076 | "version": "3.1.0", 1077 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1078 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1079 | "dev": true, 1080 | "dependencies": { 1081 | "yocto-queue": "^0.1.0" 1082 | }, 1083 | "engines": { 1084 | "node": ">=10" 1085 | }, 1086 | "funding": { 1087 | "url": "https://github.com/sponsors/sindresorhus" 1088 | } 1089 | }, 1090 | "node_modules/p-locate": { 1091 | "version": "5.0.0", 1092 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1093 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1094 | "dev": true, 1095 | "dependencies": { 1096 | "p-limit": "^3.0.2" 1097 | }, 1098 | "engines": { 1099 | "node": ">=10" 1100 | }, 1101 | "funding": { 1102 | "url": "https://github.com/sponsors/sindresorhus" 1103 | } 1104 | }, 1105 | "node_modules/parent-module": { 1106 | "version": "1.0.1", 1107 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1108 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1109 | "dev": true, 1110 | "dependencies": { 1111 | "callsites": "^3.0.0" 1112 | }, 1113 | "engines": { 1114 | "node": ">=6" 1115 | } 1116 | }, 1117 | "node_modules/parse-imports": { 1118 | "version": "2.2.1", 1119 | "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", 1120 | "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", 1121 | "dev": true, 1122 | "dependencies": { 1123 | "es-module-lexer": "^1.5.3", 1124 | "slashes": "^3.0.12" 1125 | }, 1126 | "engines": { 1127 | "node": ">= 18" 1128 | } 1129 | }, 1130 | "node_modules/path-exists": { 1131 | "version": "4.0.0", 1132 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1133 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1134 | "dev": true, 1135 | "engines": { 1136 | "node": ">=8" 1137 | } 1138 | }, 1139 | "node_modules/path-key": { 1140 | "version": "3.1.1", 1141 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1142 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1143 | "dev": true, 1144 | "engines": { 1145 | "node": ">=8" 1146 | } 1147 | }, 1148 | "node_modules/prebuildify": { 1149 | "version": "6.0.1", 1150 | "resolved": "https://registry.npmjs.org/prebuildify/-/prebuildify-6.0.1.tgz", 1151 | "integrity": "sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==", 1152 | "dev": true, 1153 | "dependencies": { 1154 | "minimist": "^1.2.5", 1155 | "mkdirp-classic": "^0.5.3", 1156 | "node-abi": "^3.3.0", 1157 | "npm-run-path": "^3.1.0", 1158 | "pump": "^3.0.0", 1159 | "tar-fs": "^2.1.0" 1160 | }, 1161 | "bin": { 1162 | "prebuildify": "bin.js" 1163 | } 1164 | }, 1165 | "node_modules/prelude-ls": { 1166 | "version": "1.2.1", 1167 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1168 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1169 | "dev": true, 1170 | "engines": { 1171 | "node": ">= 0.8.0" 1172 | } 1173 | }, 1174 | "node_modules/pump": { 1175 | "version": "3.0.0", 1176 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 1177 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 1178 | "dev": true, 1179 | "dependencies": { 1180 | "end-of-stream": "^1.1.0", 1181 | "once": "^1.3.1" 1182 | } 1183 | }, 1184 | "node_modules/punycode": { 1185 | "version": "2.3.1", 1186 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1187 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1188 | "dev": true, 1189 | "engines": { 1190 | "node": ">=6" 1191 | } 1192 | }, 1193 | "node_modules/readable-stream": { 1194 | "version": "3.6.2", 1195 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1196 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1197 | "dev": true, 1198 | "dependencies": { 1199 | "inherits": "^2.0.3", 1200 | "string_decoder": "^1.1.1", 1201 | "util-deprecate": "^1.0.1" 1202 | }, 1203 | "engines": { 1204 | "node": ">= 6" 1205 | } 1206 | }, 1207 | "node_modules/resolve-from": { 1208 | "version": "4.0.0", 1209 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1210 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1211 | "dev": true, 1212 | "engines": { 1213 | "node": ">=4" 1214 | } 1215 | }, 1216 | "node_modules/safe-buffer": { 1217 | "version": "5.2.1", 1218 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1219 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1220 | "dev": true, 1221 | "funding": [ 1222 | { 1223 | "type": "github", 1224 | "url": "https://github.com/sponsors/feross" 1225 | }, 1226 | { 1227 | "type": "patreon", 1228 | "url": "https://www.patreon.com/feross" 1229 | }, 1230 | { 1231 | "type": "consulting", 1232 | "url": "https://feross.org/support" 1233 | } 1234 | ] 1235 | }, 1236 | "node_modules/semver": { 1237 | "version": "7.6.3", 1238 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 1239 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 1240 | "dev": true, 1241 | "bin": { 1242 | "semver": "bin/semver.js" 1243 | }, 1244 | "engines": { 1245 | "node": ">=10" 1246 | } 1247 | }, 1248 | "node_modules/shebang-command": { 1249 | "version": "2.0.0", 1250 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1251 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1252 | "dev": true, 1253 | "dependencies": { 1254 | "shebang-regex": "^3.0.0" 1255 | }, 1256 | "engines": { 1257 | "node": ">=8" 1258 | } 1259 | }, 1260 | "node_modules/shebang-regex": { 1261 | "version": "3.0.0", 1262 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1263 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1264 | "dev": true, 1265 | "engines": { 1266 | "node": ">=8" 1267 | } 1268 | }, 1269 | "node_modules/slashes": { 1270 | "version": "3.0.12", 1271 | "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", 1272 | "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", 1273 | "dev": true 1274 | }, 1275 | "node_modules/spdx-exceptions": { 1276 | "version": "2.5.0", 1277 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", 1278 | "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", 1279 | "dev": true 1280 | }, 1281 | "node_modules/spdx-expression-parse": { 1282 | "version": "4.0.0", 1283 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", 1284 | "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", 1285 | "dev": true, 1286 | "dependencies": { 1287 | "spdx-exceptions": "^2.1.0", 1288 | "spdx-license-ids": "^3.0.0" 1289 | } 1290 | }, 1291 | "node_modules/spdx-license-ids": { 1292 | "version": "3.0.20", 1293 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", 1294 | "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", 1295 | "dev": true 1296 | }, 1297 | "node_modules/string_decoder": { 1298 | "version": "1.3.0", 1299 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 1300 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 1301 | "dev": true, 1302 | "dependencies": { 1303 | "safe-buffer": "~5.2.0" 1304 | } 1305 | }, 1306 | "node_modules/strip-json-comments": { 1307 | "version": "3.1.1", 1308 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1309 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1310 | "dev": true, 1311 | "engines": { 1312 | "node": ">=8" 1313 | }, 1314 | "funding": { 1315 | "url": "https://github.com/sponsors/sindresorhus" 1316 | } 1317 | }, 1318 | "node_modules/supports-color": { 1319 | "version": "7.2.0", 1320 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1321 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1322 | "dev": true, 1323 | "dependencies": { 1324 | "has-flag": "^4.0.0" 1325 | }, 1326 | "engines": { 1327 | "node": ">=8" 1328 | } 1329 | }, 1330 | "node_modules/synckit": { 1331 | "version": "0.9.2", 1332 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", 1333 | "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", 1334 | "dev": true, 1335 | "dependencies": { 1336 | "@pkgr/core": "^0.1.0", 1337 | "tslib": "^2.6.2" 1338 | }, 1339 | "engines": { 1340 | "node": "^14.18.0 || >=16.0.0" 1341 | }, 1342 | "funding": { 1343 | "url": "https://opencollective.com/unts" 1344 | } 1345 | }, 1346 | "node_modules/tar-fs": { 1347 | "version": "2.1.1", 1348 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", 1349 | "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", 1350 | "dev": true, 1351 | "dependencies": { 1352 | "chownr": "^1.1.1", 1353 | "mkdirp-classic": "^0.5.2", 1354 | "pump": "^3.0.0", 1355 | "tar-stream": "^2.1.4" 1356 | } 1357 | }, 1358 | "node_modules/tar-stream": { 1359 | "version": "2.2.0", 1360 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", 1361 | "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", 1362 | "dev": true, 1363 | "dependencies": { 1364 | "bl": "^4.0.3", 1365 | "end-of-stream": "^1.4.1", 1366 | "fs-constants": "^1.0.0", 1367 | "inherits": "^2.0.3", 1368 | "readable-stream": "^3.1.1" 1369 | }, 1370 | "engines": { 1371 | "node": ">=6" 1372 | } 1373 | }, 1374 | "node_modules/text-table": { 1375 | "version": "0.2.0", 1376 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1377 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 1378 | "dev": true 1379 | }, 1380 | "node_modules/tree-sitter": { 1381 | "version": "0.21.1", 1382 | "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz", 1383 | "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==", 1384 | "hasInstallScript": true, 1385 | "optional": true, 1386 | "peer": true, 1387 | "dependencies": { 1388 | "node-addon-api": "^8.0.0", 1389 | "node-gyp-build": "^4.8.0" 1390 | } 1391 | }, 1392 | "node_modules/tree-sitter-cli": { 1393 | "version": "0.24.4", 1394 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.24.4.tgz", 1395 | "integrity": "sha512-I4sdtDidnujYL0tR0Re9q0UJt5KrITf2m+GMHjT4LH6IC6kpM6eLzSR7RS36Z4t5ZQBjDHvg2QUJHAWQi3P2TA==", 1396 | "dev": true, 1397 | "hasInstallScript": true, 1398 | "bin": { 1399 | "tree-sitter": "cli.js" 1400 | }, 1401 | "engines": { 1402 | "node": ">=12.0.0" 1403 | } 1404 | }, 1405 | "node_modules/tslib": { 1406 | "version": "2.8.1", 1407 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 1408 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", 1409 | "dev": true 1410 | }, 1411 | "node_modules/type-check": { 1412 | "version": "0.4.0", 1413 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1414 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1415 | "dev": true, 1416 | "dependencies": { 1417 | "prelude-ls": "^1.2.1" 1418 | }, 1419 | "engines": { 1420 | "node": ">= 0.8.0" 1421 | } 1422 | }, 1423 | "node_modules/uri-js": { 1424 | "version": "4.4.1", 1425 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1426 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1427 | "dev": true, 1428 | "dependencies": { 1429 | "punycode": "^2.1.0" 1430 | } 1431 | }, 1432 | "node_modules/util-deprecate": { 1433 | "version": "1.0.2", 1434 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1435 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 1436 | "dev": true 1437 | }, 1438 | "node_modules/which": { 1439 | "version": "2.0.2", 1440 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1441 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1442 | "dev": true, 1443 | "dependencies": { 1444 | "isexe": "^2.0.0" 1445 | }, 1446 | "bin": { 1447 | "node-which": "bin/node-which" 1448 | }, 1449 | "engines": { 1450 | "node": ">= 8" 1451 | } 1452 | }, 1453 | "node_modules/word-wrap": { 1454 | "version": "1.2.5", 1455 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 1456 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 1457 | "dev": true, 1458 | "engines": { 1459 | "node": ">=0.10.0" 1460 | } 1461 | }, 1462 | "node_modules/wrappy": { 1463 | "version": "1.0.2", 1464 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1465 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1466 | "dev": true 1467 | }, 1468 | "node_modules/yocto-queue": { 1469 | "version": "0.1.0", 1470 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1471 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1472 | "dev": true, 1473 | "engines": { 1474 | "node": ">=10" 1475 | }, 1476 | "funding": { 1477 | "url": "https://github.com/sponsors/sindresorhus" 1478 | } 1479 | } 1480 | } 1481 | } 1482 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-ql", 3 | "version": "0.23.1", 4 | "description": "Semmle QL grammar for tree-sitter", 5 | "repository": "https://github.com/tree-sitter/tree-sitter-ql", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Sam Lanning", 9 | "email": "sam@samlanning.com" 10 | }, 11 | "main": "bindings/node", 12 | "types": "bindings/node", 13 | "keywords": [ 14 | "incremental", 15 | "parsing", 16 | "tree-sitter", 17 | "ql" 18 | ], 19 | "files": [ 20 | "grammar.js", 21 | "tree-sitter.json", 22 | "binding.gyp", 23 | "prebuilds/**", 24 | "bindings/node/*", 25 | "queries/*", 26 | "src/**", 27 | "*.wasm" 28 | ], 29 | "dependencies": { 30 | "node-addon-api": "^8.2.2", 31 | "node-gyp-build": "^4.8.2" 32 | }, 33 | "devDependencies": { 34 | "eslint": "^9.14.0", 35 | "eslint-config-treesitter": "1.0.2", 36 | "prebuildify": "^6.0.1", 37 | "tree-sitter-cli": "^0.24.4" 38 | }, 39 | "peerDependencies": { 40 | "tree-sitter": "^0.21.1" 41 | }, 42 | "peerDependenciesMeta": { 43 | "tree-sitter": { 44 | "optional": true 45 | } 46 | }, 47 | "scripts": { 48 | "install": "node-gyp-build", 49 | "lint": "eslint grammar.js", 50 | "prestart": "tree-sitter build --wasm", 51 | "start": "tree-sitter playground", 52 | "test": "node --test bindings/node/*_test.js" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-ql" 7 | description = "Semmle QL grammar for tree-sitter" 8 | version = "0.23.1" 9 | keywords = ["incremental", "parsing", "tree-sitter", "ql"] 10 | classifiers = [ 11 | "Intended Audience :: Developers", 12 | "License :: OSI Approved :: MIT License", 13 | "Topic :: Software Development :: Compilers", 14 | "Topic :: Text Processing :: Linguistic", 15 | "Typing :: Typed", 16 | ] 17 | authors = [{ name = "Sam Lanning", email = "sam@samlanning.com" }] 18 | requires-python = ">=3.9" 19 | license.text = "MIT" 20 | readme = "README.md" 21 | 22 | [project.urls] 23 | Homepage = "https://github.com/tree-sitter/tree-sitter-ql" 24 | 25 | [project.optional-dependencies] 26 | core = ["tree-sitter~=0.22"] 27 | 28 | [tool.cibuildwheel] 29 | build = "cp39-*" 30 | build-frontend = "build" 31 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | [ 2 | "and" 3 | "any" 4 | "as" 5 | "asc" 6 | "avg" 7 | "by" 8 | "class" 9 | "concat" 10 | "count" 11 | "desc" 12 | "else" 13 | "exists" 14 | "extends" 15 | "forall" 16 | "forex" 17 | "from" 18 | "if" 19 | "implements" 20 | "implies" 21 | "import" 22 | "in" 23 | "instanceof" 24 | "max" 25 | "min" 26 | "module" 27 | "newtype" 28 | "not" 29 | "or" 30 | "order" 31 | "rank" 32 | "select" 33 | "strictconcat" 34 | "strictcount" 35 | "strictsum" 36 | "sum" 37 | "then" 38 | "where" 39 | 40 | (false) 41 | (predicate) 42 | (result) 43 | (specialId) 44 | (super) 45 | (this) 46 | (true) 47 | ] @keyword 48 | 49 | [ 50 | "boolean" 51 | "float" 52 | "int" 53 | "date" 54 | "string" 55 | ] @type.builtin 56 | 57 | (annotName) @attribute 58 | 59 | [ 60 | "<" 61 | "<=" 62 | "=" 63 | ">" 64 | ">=" 65 | "-" 66 | "!=" 67 | "/" 68 | "*" 69 | "%" 70 | "+" 71 | "::" 72 | ] @operator 73 | 74 | [ 75 | "(" 76 | ")" 77 | "{" 78 | "}" 79 | "[" 80 | "]" 81 | ] @punctuation.bracket 82 | 83 | [ 84 | "," 85 | "|" 86 | ] @punctuation.delimiter 87 | 88 | (className) @type 89 | 90 | (varName) @variable 91 | 92 | (integer) @number 93 | (float) @number 94 | 95 | (string) @string 96 | 97 | (aritylessPredicateExpr (literalId) @function) 98 | (predicateName) @function 99 | 100 | [ 101 | (line_comment) 102 | (block_comment) 103 | (qldoc) 104 | ] @comment 105 | -------------------------------------------------------------------------------- /queries/tags.scm: -------------------------------------------------------------------------------- 1 | (classlessPredicate 2 | name: (predicateName) @name) @definition.function 3 | 4 | (memberPredicate 5 | name: (predicateName) @name) @definition.method 6 | 7 | (aritylessPredicateExpr 8 | name: (literalId) @name) @reference.call 9 | 10 | (module 11 | name: (moduleName) @name) @definition.module 12 | 13 | (dataclass 14 | name: (className) @name) @definition.class 15 | 16 | (datatype 17 | name: (className) @name) @definition.class 18 | 19 | (datatypeBranch 20 | name: (className) @name) @definition.class 21 | 22 | (qualifiedRhs 23 | name: (predicateName) @name) @reference.call 24 | 25 | (typeExpr 26 | name: (className) @name) @reference.type 27 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from os.path import isdir, join 2 | from platform import system 3 | 4 | from setuptools import Extension, find_packages, setup 5 | from setuptools.command.build import build 6 | from wheel.bdist_wheel import bdist_wheel 7 | 8 | 9 | class Build(build): 10 | def run(self): 11 | if isdir("queries"): 12 | dest = join(self.build_lib, "tree_sitter_ql", "queries") 13 | self.copy_tree("queries", dest) 14 | super().run() 15 | 16 | 17 | class BdistWheel(bdist_wheel): 18 | def get_tag(self): 19 | python, abi, platform = super().get_tag() 20 | if python.startswith("cp"): 21 | python, abi = "cp39", "abi3" 22 | return python, abi, platform 23 | 24 | 25 | setup( 26 | packages=find_packages("bindings/python"), 27 | package_dir={"": "bindings/python"}, 28 | package_data={ 29 | "tree_sitter_ql": ["*.pyi", "py.typed"], 30 | "tree_sitter_ql.queries": ["*.scm"], 31 | }, 32 | ext_package="tree_sitter_ql", 33 | ext_modules=[ 34 | Extension( 35 | name="_binding", 36 | sources=[ 37 | "bindings/python/tree_sitter_ql/binding.c", 38 | "src/parser.c", 39 | ], 40 | extra_compile_args=[ 41 | "-std=c11", 42 | "-fvisibility=hidden", 43 | ] if system() != "Windows" else [ 44 | "/std:c11", 45 | "/utf-8", 46 | ], 47 | define_macros=[ 48 | ("Py_LIMITED_API", "0x03090000"), 49 | ("PY_SSIZE_T_CLEAN", None), 50 | ("TREE_SITTER_HIDE_SYMBOLS", None), 51 | ], 52 | include_dirs=["src"], 53 | py_limited_api=True, 54 | ) 55 | ], 56 | cmdclass={ 57 | "build": Build, 58 | "bdist_wheel": BdistWheel 59 | }, 60 | zip_safe=False 61 | ) 62 | -------------------------------------------------------------------------------- /src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(disable : 4101) 18 | #elif defined(__GNUC__) || defined(__clang__) 19 | #pragma GCC diagnostic push 20 | #pragma GCC diagnostic ignored "-Wunused-variable" 21 | #endif 22 | 23 | #define Array(T) \ 24 | struct { \ 25 | T *contents; \ 26 | uint32_t size; \ 27 | uint32_t capacity; \ 28 | } 29 | 30 | /// Initialize an array. 31 | #define array_init(self) \ 32 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 33 | 34 | /// Create an empty array. 35 | #define array_new() \ 36 | { NULL, 0, 0 } 37 | 38 | /// Get a pointer to the element at a given `index` in the array. 39 | #define array_get(self, _index) \ 40 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 41 | 42 | /// Get a pointer to the first element in the array. 43 | #define array_front(self) array_get(self, 0) 44 | 45 | /// Get a pointer to the last element in the array. 46 | #define array_back(self) array_get(self, (self)->size - 1) 47 | 48 | /// Clear the array, setting its size to zero. Note that this does not free any 49 | /// memory allocated for the array's contents. 50 | #define array_clear(self) ((self)->size = 0) 51 | 52 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 53 | /// less than the array's current capacity, this function has no effect. 54 | #define array_reserve(self, new_capacity) \ 55 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 56 | 57 | /// Free any memory allocated for this array. Note that this does not free any 58 | /// memory allocated for the array's contents. 59 | #define array_delete(self) _array__delete((Array *)(self)) 60 | 61 | /// Push a new `element` onto the end of the array. 62 | #define array_push(self, element) \ 63 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 64 | (self)->contents[(self)->size++] = (element)) 65 | 66 | /// Increase the array's size by `count` elements. 67 | /// New elements are zero-initialized. 68 | #define array_grow_by(self, count) \ 69 | do { \ 70 | if ((count) == 0) break; \ 71 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 72 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 73 | (self)->size += (count); \ 74 | } while (0) 75 | 76 | /// Append all elements from one array to the end of another. 77 | #define array_push_all(self, other) \ 78 | array_extend((self), (other)->size, (other)->contents) 79 | 80 | /// Append `count` elements to the end of the array, reading their values from the 81 | /// `contents` pointer. 82 | #define array_extend(self, count, contents) \ 83 | _array__splice( \ 84 | (Array *)(self), array_elem_size(self), (self)->size, \ 85 | 0, count, contents \ 86 | ) 87 | 88 | /// Remove `old_count` elements from the array starting at the given `index`. At 89 | /// the same index, insert `new_count` new elements, reading their values from the 90 | /// `new_contents` pointer. 91 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 92 | _array__splice( \ 93 | (Array *)(self), array_elem_size(self), _index, \ 94 | old_count, new_count, new_contents \ 95 | ) 96 | 97 | /// Insert one `element` into the array at the given `index`. 98 | #define array_insert(self, _index, element) \ 99 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 100 | 101 | /// Remove one element from the array at the given `index`. 102 | #define array_erase(self, _index) \ 103 | _array__erase((Array *)(self), array_elem_size(self), _index) 104 | 105 | /// Pop the last element off the array, returning the element by value. 106 | #define array_pop(self) ((self)->contents[--(self)->size]) 107 | 108 | /// Assign the contents of one array to another, reallocating if necessary. 109 | #define array_assign(self, other) \ 110 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 111 | 112 | /// Swap one array with another 113 | #define array_swap(self, other) \ 114 | _array__swap((Array *)(self), (Array *)(other)) 115 | 116 | /// Get the size of the array contents 117 | #define array_elem_size(self) (sizeof *(self)->contents) 118 | 119 | /// Search a sorted array for a given `needle` value, using the given `compare` 120 | /// callback to determine the order. 121 | /// 122 | /// If an existing element is found to be equal to `needle`, then the `index` 123 | /// out-parameter is set to the existing value's index, and the `exists` 124 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 125 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 126 | /// is set to false. 127 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 128 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 129 | 130 | /// Search a sorted array for a given `needle` value, using integer comparisons 131 | /// of a given struct field (specified with a leading dot) to determine the order. 132 | /// 133 | /// See also `array_search_sorted_with`. 134 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 135 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 136 | 137 | /// Insert a given `value` into a sorted array, using the given `compare` 138 | /// callback to determine the order. 139 | #define array_insert_sorted_with(self, compare, value) \ 140 | do { \ 141 | unsigned _index, _exists; \ 142 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 143 | if (!_exists) array_insert(self, _index, value); \ 144 | } while (0) 145 | 146 | /// Insert a given `value` into a sorted array, using integer comparisons of 147 | /// a given struct field (specified with a leading dot) to determine the order. 148 | /// 149 | /// See also `array_search_sorted_by`. 150 | #define array_insert_sorted_by(self, field, value) \ 151 | do { \ 152 | unsigned _index, _exists; \ 153 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 154 | if (!_exists) array_insert(self, _index, value); \ 155 | } while (0) 156 | 157 | // Private 158 | 159 | typedef Array(void) Array; 160 | 161 | /// This is not what you're looking for, see `array_delete`. 162 | static inline void _array__delete(Array *self) { 163 | if (self->contents) { 164 | ts_free(self->contents); 165 | self->contents = NULL; 166 | self->size = 0; 167 | self->capacity = 0; 168 | } 169 | } 170 | 171 | /// This is not what you're looking for, see `array_erase`. 172 | static inline void _array__erase(Array *self, size_t element_size, 173 | uint32_t index) { 174 | assert(index < self->size); 175 | char *contents = (char *)self->contents; 176 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 177 | (self->size - index - 1) * element_size); 178 | self->size--; 179 | } 180 | 181 | /// This is not what you're looking for, see `array_reserve`. 182 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 183 | if (new_capacity > self->capacity) { 184 | if (self->contents) { 185 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 186 | } else { 187 | self->contents = ts_malloc(new_capacity * element_size); 188 | } 189 | self->capacity = new_capacity; 190 | } 191 | } 192 | 193 | /// This is not what you're looking for, see `array_assign`. 194 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 195 | _array__reserve(self, element_size, other->size); 196 | self->size = other->size; 197 | memcpy(self->contents, other->contents, self->size * element_size); 198 | } 199 | 200 | /// This is not what you're looking for, see `array_swap`. 201 | static inline void _array__swap(Array *self, Array *other) { 202 | Array swap = *other; 203 | *other = *self; 204 | *self = swap; 205 | } 206 | 207 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 208 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 209 | uint32_t new_size = self->size + count; 210 | if (new_size > self->capacity) { 211 | uint32_t new_capacity = self->capacity * 2; 212 | if (new_capacity < 8) new_capacity = 8; 213 | if (new_capacity < new_size) new_capacity = new_size; 214 | _array__reserve(self, element_size, new_capacity); 215 | } 216 | } 217 | 218 | /// This is not what you're looking for, see `array_splice`. 219 | static inline void _array__splice(Array *self, size_t element_size, 220 | uint32_t index, uint32_t old_count, 221 | uint32_t new_count, const void *elements) { 222 | uint32_t new_size = self->size + new_count - old_count; 223 | uint32_t old_end = index + old_count; 224 | uint32_t new_end = index + new_count; 225 | assert(old_end <= self->size); 226 | 227 | _array__reserve(self, element_size, new_size); 228 | 229 | char *contents = (char *)self->contents; 230 | if (self->size > old_end) { 231 | memmove( 232 | contents + new_end * element_size, 233 | contents + old_end * element_size, 234 | (self->size - old_end) * element_size 235 | ); 236 | } 237 | if (new_count > 0) { 238 | if (elements) { 239 | memcpy( 240 | (contents + index * element_size), 241 | elements, 242 | new_count * element_size 243 | ); 244 | } else { 245 | memset( 246 | (contents + index * element_size), 247 | 0, 248 | new_count * element_size 249 | ); 250 | } 251 | } 252 | self->size += new_count - old_count; 253 | } 254 | 255 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 256 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 257 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 258 | do { \ 259 | *(_index) = start; \ 260 | *(_exists) = false; \ 261 | uint32_t size = (self)->size - *(_index); \ 262 | if (size == 0) break; \ 263 | int comparison; \ 264 | while (size > 1) { \ 265 | uint32_t half_size = size / 2; \ 266 | uint32_t mid_index = *(_index) + half_size; \ 267 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 268 | if (comparison <= 0) *(_index) = mid_index; \ 269 | size -= half_size; \ 270 | } \ 271 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 272 | if (comparison == 0) *(_exists) = true; \ 273 | else if (comparison < 0) *(_index) += 1; \ 274 | } while (0) 275 | 276 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 277 | /// parameter by reference in order to work with the generic sorting function above. 278 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 279 | 280 | #ifdef _MSC_VER 281 | #pragma warning(default : 4101) 282 | #elif defined(__GNUC__) || defined(__clang__) 283 | #pragma GCC diagnostic pop 284 | #endif 285 | 286 | #ifdef __cplusplus 287 | } 288 | #endif 289 | 290 | #endif // TREE_SITTER_ARRAY_H_ 291 | -------------------------------------------------------------------------------- /src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | #endif 22 | 23 | typedef struct { 24 | TSFieldId field_id; 25 | uint8_t child_index; 26 | bool inherited; 27 | } TSFieldMapEntry; 28 | 29 | typedef struct { 30 | uint16_t index; 31 | uint16_t length; 32 | } TSFieldMapSlice; 33 | 34 | typedef struct { 35 | bool visible; 36 | bool named; 37 | bool supertype; 38 | } TSSymbolMetadata; 39 | 40 | typedef struct TSLexer TSLexer; 41 | 42 | struct TSLexer { 43 | int32_t lookahead; 44 | TSSymbol result_symbol; 45 | void (*advance)(TSLexer *, bool); 46 | void (*mark_end)(TSLexer *); 47 | uint32_t (*get_column)(TSLexer *); 48 | bool (*is_at_included_range_start)(const TSLexer *); 49 | bool (*eof)(const TSLexer *); 50 | void (*log)(const TSLexer *, const char *, ...); 51 | }; 52 | 53 | typedef enum { 54 | TSParseActionTypeShift, 55 | TSParseActionTypeReduce, 56 | TSParseActionTypeAccept, 57 | TSParseActionTypeRecover, 58 | } TSParseActionType; 59 | 60 | typedef union { 61 | struct { 62 | uint8_t type; 63 | TSStateId state; 64 | bool extra; 65 | bool repetition; 66 | } shift; 67 | struct { 68 | uint8_t type; 69 | uint8_t child_count; 70 | TSSymbol symbol; 71 | int16_t dynamic_precedence; 72 | uint16_t production_id; 73 | } reduce; 74 | uint8_t type; 75 | } TSParseAction; 76 | 77 | typedef struct { 78 | uint16_t lex_state; 79 | uint16_t external_lex_state; 80 | } TSLexMode; 81 | 82 | typedef union { 83 | TSParseAction action; 84 | struct { 85 | uint8_t count; 86 | bool reusable; 87 | } entry; 88 | } TSParseActionEntry; 89 | 90 | typedef struct { 91 | int32_t start; 92 | int32_t end; 93 | } TSCharacterRange; 94 | 95 | struct TSLanguage { 96 | uint32_t version; 97 | uint32_t symbol_count; 98 | uint32_t alias_count; 99 | uint32_t token_count; 100 | uint32_t external_token_count; 101 | uint32_t state_count; 102 | uint32_t large_state_count; 103 | uint32_t production_id_count; 104 | uint32_t field_count; 105 | uint16_t max_alias_sequence_length; 106 | const uint16_t *parse_table; 107 | const uint16_t *small_parse_table; 108 | const uint32_t *small_parse_table_map; 109 | const TSParseActionEntry *parse_actions; 110 | const char * const *symbol_names; 111 | const char * const *field_names; 112 | const TSFieldMapSlice *field_map_slices; 113 | const TSFieldMapEntry *field_map_entries; 114 | const TSSymbolMetadata *symbol_metadata; 115 | const TSSymbol *public_symbol_map; 116 | const uint16_t *alias_map; 117 | const TSSymbol *alias_sequences; 118 | const TSLexMode *lex_modes; 119 | bool (*lex_fn)(TSLexer *, TSStateId); 120 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 121 | TSSymbol keyword_capture_token; 122 | struct { 123 | const bool *states; 124 | const TSSymbol *symbol_map; 125 | void *(*create)(void); 126 | void (*destroy)(void *); 127 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 128 | unsigned (*serialize)(void *, char *); 129 | void (*deserialize)(void *, const char *, unsigned); 130 | } external_scanner; 131 | const TSStateId *primary_state_ids; 132 | }; 133 | 134 | static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 135 | uint32_t index = 0; 136 | uint32_t size = len - index; 137 | while (size > 1) { 138 | uint32_t half_size = size / 2; 139 | uint32_t mid_index = index + half_size; 140 | TSCharacterRange *range = &ranges[mid_index]; 141 | if (lookahead >= range->start && lookahead <= range->end) { 142 | return true; 143 | } else if (lookahead > range->end) { 144 | index = mid_index; 145 | } 146 | size -= half_size; 147 | } 148 | TSCharacterRange *range = &ranges[index]; 149 | return (lookahead >= range->start && lookahead <= range->end); 150 | } 151 | 152 | /* 153 | * Lexer Macros 154 | */ 155 | 156 | #ifdef _MSC_VER 157 | #define UNUSED __pragma(warning(suppress : 4101)) 158 | #else 159 | #define UNUSED __attribute__((unused)) 160 | #endif 161 | 162 | #define START_LEXER() \ 163 | bool result = false; \ 164 | bool skip = false; \ 165 | UNUSED \ 166 | bool eof = false; \ 167 | int32_t lookahead; \ 168 | goto start; \ 169 | next_state: \ 170 | lexer->advance(lexer, skip); \ 171 | start: \ 172 | skip = false; \ 173 | lookahead = lexer->lookahead; 174 | 175 | #define ADVANCE(state_value) \ 176 | { \ 177 | state = state_value; \ 178 | goto next_state; \ 179 | } 180 | 181 | #define ADVANCE_MAP(...) \ 182 | { \ 183 | static const uint16_t map[] = { __VA_ARGS__ }; \ 184 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 185 | if (map[i] == lookahead) { \ 186 | state = map[i + 1]; \ 187 | goto next_state; \ 188 | } \ 189 | } \ 190 | } 191 | 192 | #define SKIP(state_value) \ 193 | { \ 194 | skip = true; \ 195 | state = state_value; \ 196 | goto next_state; \ 197 | } 198 | 199 | #define ACCEPT_TOKEN(symbol_value) \ 200 | result = true; \ 201 | lexer->result_symbol = symbol_value; \ 202 | lexer->mark_end(lexer); 203 | 204 | #define END_STATE() return result; 205 | 206 | /* 207 | * Parse Table Macros 208 | */ 209 | 210 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 211 | 212 | #define STATE(id) id 213 | 214 | #define ACTIONS(id) id 215 | 216 | #define SHIFT(state_value) \ 217 | {{ \ 218 | .shift = { \ 219 | .type = TSParseActionTypeShift, \ 220 | .state = (state_value) \ 221 | } \ 222 | }} 223 | 224 | #define SHIFT_REPEAT(state_value) \ 225 | {{ \ 226 | .shift = { \ 227 | .type = TSParseActionTypeShift, \ 228 | .state = (state_value), \ 229 | .repetition = true \ 230 | } \ 231 | }} 232 | 233 | #define SHIFT_EXTRA() \ 234 | {{ \ 235 | .shift = { \ 236 | .type = TSParseActionTypeShift, \ 237 | .extra = true \ 238 | } \ 239 | }} 240 | 241 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 242 | {{ \ 243 | .reduce = { \ 244 | .type = TSParseActionTypeReduce, \ 245 | .symbol = symbol_name, \ 246 | .child_count = children, \ 247 | .dynamic_precedence = precedence, \ 248 | .production_id = prod_id \ 249 | }, \ 250 | }} 251 | 252 | #define RECOVER() \ 253 | {{ \ 254 | .type = TSParseActionTypeRecover \ 255 | }} 256 | 257 | #define ACCEPT_INPUT() \ 258 | {{ \ 259 | .type = TSParseActionTypeAccept \ 260 | }} 261 | 262 | #ifdef __cplusplus 263 | } 264 | #endif 265 | 266 | #endif // TREE_SITTER_PARSER_H_ 267 | -------------------------------------------------------------------------------- /test/corpus/basic.txt: -------------------------------------------------------------------------------- 1 | ============ 2 | Basic select 3 | ============ 4 | 5 | import javascript 6 | 7 | select 8 | "hello world" as foo, 9 | "other", 10 | "string with escaped \\ backslashes \" quotes \n\r\t whitespace", 11 | 1234, 12 | 1234.4321, 13 | true, 14 | false 15 | 16 | --- 17 | 18 | (ql 19 | (moduleMember (importDirective (importModuleExpr (moduleExpr (simpleId))))) 20 | (moduleMember (select (asExprs 21 | (asExpr (literal (string)) (varName (simpleId))) 22 | (asExpr (literal (string))) 23 | (asExpr (literal (string))) 24 | (asExpr (literal (integer))) 25 | (asExpr (literal (float))) 26 | (asExpr (literal (bool (true)))) 27 | (asExpr (literal (bool (false)))))))) 28 | 29 | ============ 30 | Select with variables and order by 31 | ============ 32 | 33 | from 34 | Foo foo, 35 | some::submodule::Bar bar, 36 | @dbtype bar, 37 | boolean b, 38 | date d, 39 | float f, 40 | int i, 41 | string s 42 | select "hello world" 43 | order by foo, bar desc, baz asc 44 | 45 | --- 46 | 47 | (ql (moduleMember 48 | (select 49 | (varDecl (typeExpr (className)) (varName (simpleId))) 50 | (varDecl (typeExpr (moduleExpr (moduleExpr (simpleId)) (simpleId)) (className)) (varName (simpleId))) 51 | (varDecl (typeExpr (dbtype)) (varName (simpleId))) 52 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 53 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 54 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 55 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 56 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 57 | (asExprs 58 | (asExpr (literal (string)))) 59 | (orderBys 60 | (orderBy (variable (varName (simpleId)))) 61 | (orderBy (variable (varName (simpleId))) (direction)) 62 | (orderBy (variable (varName (simpleId))) (direction)))))) 63 | 64 | ======================== 65 | Annotations and comments 66 | ======================== 67 | 68 | private import foo // some other comment 69 | 70 | /* 71 | * Some comment 72 | */ 73 | pragma[noinline] 74 | bindingset[foobar, this] 75 | import bar 76 | 77 | --- 78 | 79 | (ql 80 | (moduleMember (annotation (annotName)) (importDirective (importModuleExpr (moduleExpr (simpleId))))) 81 | (line_comment) (block_comment) 82 | (moduleMember 83 | (annotation (annotName) (annotArg (simpleId))) 84 | (annotation (annotName) (annotArg (simpleId)) (annotArg (this))) 85 | (importDirective (importModuleExpr (moduleExpr (simpleId)))))) 86 | -------------------------------------------------------------------------------- /test/corpus/class.txt: -------------------------------------------------------------------------------- 1 | =========== 2 | empty class 3 | =========== 4 | 5 | class Foo extends Bar {} 6 | 7 | --- 8 | (ql (moduleMember (dataclass (className) (typeExpr (className))))) 9 | 10 | =================================== 11 | class with characteristic predicate 12 | =================================== 13 | 14 | abstract class Foo extends Bar { 15 | 16 | pragma[inline] 17 | Foo() { 18 | this = this 19 | } 20 | 21 | } 22 | 23 | --- 24 | 25 | (ql (moduleMember 26 | (annotation (annotName)) 27 | (dataclass (className) (typeExpr (className)) 28 | (classMember (annotation (annotName) (annotArg (simpleId))) 29 | (charpred (className) 30 | (comp_term (variable (this)) (compop) (variable (this)))))))) 31 | ================== 32 | class with members 33 | ================== 34 | 35 | class X extends Y { 36 | m::F f; 37 | 38 | m::F a() { 39 | result = f 40 | } 41 | } 42 | 43 | --- 44 | 45 | (ql (moduleMember 46 | (dataclass (className) (typeExpr (className)) 47 | (classMember (field (varDecl (typeExpr (moduleExpr (simpleId)) (className)) (varName (simpleId))))) 48 | (classMember (memberPredicate (typeExpr (moduleExpr (simpleId)) (className)) (predicateName) 49 | (body (comp_term (variable (result)) (compop) (variable (varName (simpleId)))))))))) 50 | 51 | =========== 52 | class alias 53 | =========== 54 | 55 | class X = foo::Bas; 56 | 57 | --- 58 | (ql (moduleMember 59 | (dataclass (className) (typeAliasBody (typeExpr (moduleExpr (simpleId)) (className)))))) 60 | 61 | 62 | ================ 63 | class instanceof 64 | ================ 65 | 66 | class X extends Y1, Y2 instanceof Z1, Z2 { 67 | X() { none() } 68 | } 69 | 70 | --- 71 | 72 | (ql 73 | (moduleMember 74 | (dataclass 75 | (className) 76 | (typeExpr 77 | (className)) 78 | (typeExpr 79 | (className)) 80 | (typeExpr 81 | (className)) 82 | (typeExpr 83 | (className)) 84 | (classMember 85 | (charpred 86 | (className) 87 | (special_call 88 | (specialId))))))) -------------------------------------------------------------------------------- /test/corpus/ctf.txt: -------------------------------------------------------------------------------- 1 | ========================= 2 | dataflow example from ctf 3 | ========================= 4 | 5 | from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink 6 | where cfg.hasFlowPath(source, sink) 7 | select sink.getNode(), source, sink, "Potential XSS vulnerability in plugin." 8 | 9 | --- 10 | 11 | (ql (moduleMember 12 | (select 13 | (varDecl (typeExpr (className)) (varName (simpleId))) 14 | (varDecl (typeExpr (moduleExpr (simpleId)) (className)) (varName (simpleId))) 15 | (varDecl (typeExpr (moduleExpr (simpleId)) (className)) (varName (simpleId))) 16 | (qualified_expr 17 | (variable (varName (simpleId))) 18 | (qualifiedRhs (predicateName) (variable (varName (simpleId))) (variable (varName (simpleId))))) 19 | (asExprs 20 | (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))) 21 | (asExpr (variable (varName (simpleId)))) 22 | (asExpr (variable (varName (simpleId)))) 23 | (asExpr (literal (string))))))) -------------------------------------------------------------------------------- /test/corpus/expr.txt: -------------------------------------------------------------------------------- 1 | ==== 2 | cast 3 | ==== 4 | 5 | select (Foo) f 6 | 7 | --- 8 | (ql (moduleMember (select (asExprs (asExpr (prefix_cast (typeExpr (className)) (variable (varName (simpleId))))))))) 9 | ======== 10 | dontcare 11 | ======== 12 | 13 | select foo(_) 14 | 15 | --- 16 | (ql (moduleMember (select (asExprs (asExpr (call_or_unqual_agg_expr (aritylessPredicateExpr (literalId)) (call_body (underscore)))))))) 17 | ==== 18 | unop 19 | ==== 20 | 21 | select - 5, + 5 22 | 23 | --- 24 | (ql (moduleMember (select (asExprs (asExpr (unary_expr (unop) (literal (integer)))) (asExpr (unary_expr (unop) (literal (integer)))))))) 25 | ===== 26 | binop 27 | ===== 28 | 29 | select 5 + 5, 5 - 5, 5 * 5, 5 / 5, 5 % 5 30 | 31 | --- 32 | 33 | (ql (moduleMember 34 | (select 35 | (asExprs 36 | (asExpr (add_expr (literal (integer)) (addop) (literal (integer)))) 37 | (asExpr (add_expr (literal (integer)) (addop) (literal (integer)))) 38 | (asExpr (mul_expr (literal (integer)) (mulop) (literal (integer)))) 39 | (asExpr (mul_expr (literal (integer)) (mulop) (literal (integer)))) 40 | (asExpr (mul_expr (literal (integer)) (mulop) (literal (integer)))))))) 41 | 42 | =========== 43 | set literal 44 | =========== 45 | 46 | select [1,2,4] 47 | 48 | --- 49 | 50 | (ql (moduleMember 51 | (select 52 | (asExprs 53 | (asExpr 54 | (set_literal 55 | (literal (integer)) 56 | (literal (integer)) 57 | (literal (integer)))))))) 58 | 59 | ==================== 60 | uniqueness aggregate 61 | ==================== 62 | 63 | select unique(int x | x = 1 | x) 64 | 65 | --- 66 | 67 | (ql (moduleMember 68 | (select 69 | (asExprs 70 | (asExpr 71 | (aggregate 72 | (aggId) 73 | (full_aggregate_body 74 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 75 | (comp_term (variable (varName (simpleId))) (compop) (literal (integer))) 76 | (asExprs (asExpr (variable (varName (simpleId)))))))))))) 77 | 78 | ================ 79 | binop precedence 80 | ================ 81 | 82 | select 83 | // left associative 84 | 5 + 5 - 5, 85 | 5 - 5 + 5, 86 | // mul binds tighter 87 | 5 + 5 * 5, 88 | 5 + 5 / 5, 89 | 5 * 5 + 5, 90 | 5 / 5 + 5, 91 | // left associative 92 | 5 / 5 * 5, 93 | 5 * 5 / 5, 94 | // mod tighter, 95 | 5 * 5 % 5, 96 | 5 % 5 * 5 97 | 98 | --- 99 | 100 | (ql (moduleMember (select (line_comment) 101 | (asExprs 102 | (asExpr (add_expr (add_expr (literal (integer)) (addop) (literal (integer))) (addop) (literal (integer)))) 103 | (asExpr (add_expr (add_expr (literal (integer)) (addop) (literal (integer))) (addop) (literal (integer)))) 104 | (line_comment) 105 | (asExpr (add_expr (literal (integer)) (addop) (mul_expr (literal (integer)) (mulop) (literal (integer))))) 106 | (asExpr (add_expr (literal (integer)) (addop) (mul_expr (literal (integer)) (mulop) (literal (integer))))) 107 | (asExpr (add_expr (mul_expr (literal (integer)) (mulop) (literal (integer))) (addop) (literal (integer)))) 108 | (asExpr (add_expr (mul_expr (literal (integer)) (mulop) (literal (integer))) (addop) (literal (integer)))) 109 | (line_comment) 110 | (asExpr (mul_expr (mul_expr (literal (integer)) (mulop) (literal (integer))) (mulop) (literal (integer)))) 111 | (asExpr (mul_expr (mul_expr (literal (integer)) (mulop) (literal (integer))) (mulop) (literal (integer)))) 112 | (line_comment) 113 | (asExpr (mul_expr (mul_expr (literal (integer)) (mulop) (literal (integer))) (mulop) (literal (integer)))) 114 | (asExpr (mul_expr (mul_expr (literal (integer)) (mulop) (literal (integer))) (mulop) (literal (integer)))))))) 115 | 116 | =========================== 117 | unary minus and prefix cast 118 | =========================== 119 | 120 | where x = -(float) -7 121 | select 0 122 | 123 | --- 124 | 125 | (ql (moduleMember 126 | (select 127 | (comp_term 128 | (variable (varName (simpleId))) 129 | (compop) 130 | (unary_expr 131 | (unop) 132 | (prefix_cast 133 | (typeExpr (primitiveType)) 134 | (unary_expr 135 | (unop) 136 | (literal (integer)))))) 137 | (asExprs (asExpr (literal (integer))))))) 138 | 139 | ======================== 140 | unary minus and non-cast 141 | ======================== 142 | 143 | where x = -(foo) -7 144 | select 0 145 | 146 | --- 147 | 148 | (ql (moduleMember 149 | (select 150 | (comp_term 151 | (variable (varName (simpleId))) 152 | (compop) 153 | (add_expr 154 | (unary_expr 155 | (unop) 156 | (par_expr (variable (varName (simpleId))))) 157 | (addop) 158 | (literal (integer)))) 159 | (asExprs (asExpr (literal (integer))))))) 160 | 161 | ============================== 162 | unary minus and multiplication 163 | ============================== 164 | 165 | where x = -a * b 166 | select 0 167 | 168 | --- 169 | 170 | (ql (moduleMember 171 | (select 172 | (comp_term 173 | (variable (varName (simpleId))) 174 | (compop) 175 | (mul_expr 176 | (unary_expr 177 | (unop) 178 | (variable (varName (simpleId)))) 179 | (mulop) 180 | (variable (varName (simpleId))))) 181 | (asExprs (asExpr (literal (integer))))))) 182 | 183 | ======================== 184 | expression-level pragmas 185 | ======================== 186 | 187 | from int i 188 | where i = pragma[only_bind_out](5) 189 | select i 190 | 191 | --- 192 | 193 | (ql (moduleMember (select 194 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 195 | (comp_term 196 | (variable (varName (simpleId))) 197 | (compop) 198 | (expr_annotation 199 | (annotName) 200 | (annotName) 201 | (literal (integer)))) 202 | (asExprs (asExpr (variable (varName (simpleId)))))))) 203 | 204 | =========================== 205 | unary minus and prefix cast 206 | =========================== 207 | 208 | where x = -(float) -7 209 | select 0 210 | 211 | --- 212 | 213 | (ql (moduleMember 214 | (select 215 | (comp_term 216 | (variable (varName (simpleId))) 217 | (compop) 218 | (unary_expr 219 | (unop) 220 | (prefix_cast 221 | (typeExpr (primitiveType)) 222 | (unary_expr 223 | (unop) 224 | (literal (integer)))))) 225 | (asExprs (asExpr (literal (integer))))))) 226 | 227 | ======================== 228 | unary minus and non-cast 229 | ======================== 230 | 231 | where x = -(foo) -7 232 | select 0 233 | 234 | --- 235 | 236 | (ql (moduleMember 237 | (select 238 | (comp_term 239 | (variable (varName (simpleId))) 240 | (compop) 241 | (add_expr 242 | (unary_expr 243 | (unop) 244 | (par_expr (variable (varName (simpleId))))) 245 | (addop) 246 | (literal (integer)))) 247 | (asExprs (asExpr (literal (integer))))))) 248 | 249 | 250 | =============================== 251 | set literal with trailing comma 252 | =============================== 253 | 254 | where x in [1,2,] 255 | select x 256 | 257 | --- 258 | 259 | (ql (moduleMember 260 | (select 261 | (in_expr 262 | (variable (varName (simpleId))) 263 | (set_literal 264 | (literal (integer)) 265 | (literal (integer)))) 266 | (asExprs (asExpr (variable (varName (simpleId)))))))) 267 | -------------------------------------------------------------------------------- /test/corpus/formula.txt: -------------------------------------------------------------------------------- 1 | =========== 2 | comparisons 3 | =========== 4 | 5 | from File f 6 | where (f = f) 7 | or f != f 8 | and f < f 9 | and (f > f or f <= f) 10 | and f >= f 11 | select f 12 | 13 | --- 14 | 15 | (ql (moduleMember 16 | (select 17 | (varDecl (typeExpr (className)) (varName (simpleId))) 18 | (disjunction 19 | (par_expr (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))) 20 | (conjunction 21 | (conjunction 22 | (conjunction 23 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 24 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))) 25 | (par_expr (disjunction 26 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 27 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))))) 28 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))))) 29 | (asExprs (asExpr (variable (varName (simpleId)))))))) 30 | 31 | ========== 32 | instanceof 33 | ========== 34 | 35 | from Foo f 36 | where f instanceof Foo 37 | select f 38 | 39 | --- 40 | 41 | (ql (moduleMember 42 | (select 43 | (varDecl (typeExpr (className)) (varName (simpleId))) 44 | (instance_of (variable (varName (simpleId))) (typeExpr (className))) 45 | (asExprs (asExpr (variable (varName (simpleId)))))))) 46 | 47 | ===== 48 | range 49 | ===== 50 | 51 | from int i 52 | where i in [0..10] 53 | select i 54 | 55 | --- 56 | 57 | (ql (moduleMember 58 | (select 59 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 60 | (in_expr (variable (varName (simpleId))) (range (literal (integer)) (literal (integer)))) 61 | (asExprs (asExpr (variable (varName (simpleId)))))))) 62 | 63 | ===== 64 | set literals 65 | ===== 66 | 67 | from int i 68 | where i in [1, 2] 69 | select i 70 | 71 | --- 72 | 73 | (ql (moduleMember 74 | (select 75 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 76 | (in_expr (variable (varName (simpleId))) (set_literal (literal (integer)) (literal (integer)))) 77 | (asExprs (asExpr (variable (varName (simpleId)))))))) 78 | 79 | ================= 80 | predicateRef call 81 | ================= 82 | 83 | from int i 84 | where bar(i) and module::baz+() 85 | select i 86 | 87 | --- 88 | 89 | (ql (moduleMember 90 | (select 91 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 92 | (conjunction 93 | (call_or_unqual_agg_expr (aritylessPredicateExpr (literalId)) (call_body (variable (varName (simpleId))))) 94 | (call_or_unqual_agg_expr (aritylessPredicateExpr (moduleExpr (simpleId)) (literalId)) (closure) (call_body))) 95 | (asExprs (asExpr (variable (varName (simpleId)))))))) 96 | ================================= 97 | calls with results & method calls 98 | ================================= 99 | 100 | from int i 101 | select i.foo+(), 1.foo(), 1.1.foo() 102 | 103 | --- 104 | (ql (moduleMember 105 | (select 106 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 107 | (asExprs 108 | (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName) (closure)))) 109 | (asExpr (qualified_expr (literal (integer)) (qualifiedRhs (predicateName)))) 110 | (asExpr (qualified_expr (literal (float)) (qualifiedRhs (predicateName)))))))) 111 | 112 | ============== 113 | quantification 114 | ============== 115 | 116 | 117 | from Foo f 118 | where exists(f.aThing()) 119 | or exists(Foo f | f.aThing()) 120 | or exists(Foo f | f.aThing() | f.aThing()) 121 | or forall(Foo f | f.aThing() | f.aThing()) 122 | or forex(Foo f | f.aThing() | f.aThing()) 123 | select f 124 | 125 | --- 126 | 127 | (ql (moduleMember 128 | (select 129 | (varDecl (typeExpr (className)) (varName (simpleId))) 130 | (disjunction 131 | (disjunction 132 | (disjunction 133 | (disjunction 134 | (quantified (quantifier) (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))) 135 | (quantified (quantifier) (varDecl (typeExpr (className)) (varName (simpleId))) 136 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))))) 137 | (quantified (quantifier) (varDecl (typeExpr (className)) (varName (simpleId))) 138 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) 139 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))))) 140 | (quantified (quantifier) (varDecl (typeExpr (className)) (varName (simpleId))) 141 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) 142 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))))) 143 | (quantified (quantifier) (varDecl (typeExpr (className)) (varName (simpleId))) 144 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) 145 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))))) 146 | (asExprs (asExpr (variable (varName (simpleId)))))))) 147 | 148 | ================== 149 | unary op ambiguity 150 | ================== 151 | 152 | from int x 153 | where x = -1 and any() 154 | select x 155 | 156 | --- 157 | 158 | (ql (moduleMember 159 | (select 160 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) 161 | (conjunction 162 | (comp_term 163 | (variable (varName (simpleId))) 164 | (compop) 165 | (unary_expr (unop) (literal (integer)))) 166 | (aggregate (aggId))) 167 | (asExprs (asExpr (variable (varName (simpleId)))))))) 168 | 169 | ==================== 170 | unary op ambiguity 2 171 | ==================== 172 | 173 | where -1 in [-1..1] 174 | select "yes" 175 | 176 | --- 177 | 178 | (ql (moduleMember 179 | (select 180 | (in_expr 181 | (unary_expr (unop) (literal (integer))) 182 | (range 183 | (unary_expr (unop) (literal (integer))) 184 | (literal (integer)))) 185 | (asExprs (asExpr (literal (string))))))) -------------------------------------------------------------------------------- /test/corpus/modules.txt: -------------------------------------------------------------------------------- 1 | ====== 2 | module 3 | ====== 4 | 5 | module foo { 6 | module bar { 7 | import woo 8 | 9 | predicate baz(); 10 | } 11 | } 12 | 13 | --- 14 | 15 | (ql (moduleMember 16 | (module (moduleName (simpleId)) (moduleMember 17 | (module (moduleName (simpleId)) 18 | (moduleMember (importDirective (importModuleExpr (moduleExpr (simpleId))))) 19 | (moduleMember (classlessPredicate (predicate) (predicateName) (empty)))))))) 20 | 21 | ============ 22 | module alias 23 | ============ 24 | 25 | module foo = bar::baz; 26 | 27 | --- 28 | 29 | (ql (moduleMember (module (moduleName (simpleId)) (moduleAliasBody (moduleExpr (moduleExpr (simpleId)) (simpleId)))))) 30 | 31 | ============================== 32 | parameterised module signature 33 | ============================== 34 | 35 | signature int supplyInt(); 36 | 37 | signature module SupplyInt { 38 | int get(); 39 | class C extends Foo, Bar; 40 | predicate baz(C c); 41 | } 42 | 43 | --- 44 | 45 | (ql 46 | (moduleMember 47 | (annotation 48 | (annotName)) 49 | (classlessPredicate 50 | (typeExpr 51 | (primitiveType)) 52 | (predicateName) 53 | (empty))) 54 | (moduleMember 55 | (annotation 56 | (annotName)) 57 | (module 58 | (moduleName 59 | (simpleId)) 60 | (moduleMember 61 | (classlessPredicate 62 | (typeExpr 63 | (primitiveType)) 64 | (predicateName) 65 | (empty))) 66 | (moduleMember 67 | (dataclass 68 | (className) 69 | (typeExpr 70 | (className)) 71 | (typeExpr 72 | (className)))) 73 | (moduleMember 74 | (classlessPredicate 75 | (predicate) 76 | (predicateName) 77 | (varDecl 78 | (typeExpr 79 | (className)) 80 | (varName 81 | (simpleId))) 82 | (empty)))))) 83 | 84 | ================================ 85 | parameterised module declaration 86 | ================================ 87 | 88 | module PModule { 89 | int foo() { result = s1() + S2::get() } 90 | } 91 | 92 | --- 93 | 94 | (ql 95 | (moduleMember 96 | (module 97 | (moduleName 98 | (simpleId)) 99 | (moduleParam 100 | (signatureExpr 101 | (predicateExpr 102 | (aritylessPredicateExpr 103 | (literalId)) 104 | (integer))) 105 | (simpleId)) 106 | (moduleParam 107 | (signatureExpr 108 | (typeExpr 109 | (className))) 110 | (simpleId)) 111 | (moduleMember 112 | (classlessPredicate 113 | (typeExpr 114 | (primitiveType)) 115 | (predicateName) 116 | (body 117 | (comp_term 118 | (variable 119 | (result)) 120 | (compop) 121 | (add_expr 122 | (call_or_unqual_agg_expr 123 | (aritylessPredicateExpr 124 | (literalId)) 125 | (call_body)) 126 | (addop) 127 | (call_or_unqual_agg_expr 128 | (aritylessPredicateExpr 129 | (moduleExpr 130 | (simpleId)) 131 | (literalId)) 132 | (call_body)))))))))) 133 | 134 | =============================== 135 | parameterised module implements 136 | =============================== 137 | 138 | module Supply11 implements SupplyInt { 139 | int get() { result = 11 } 140 | } 141 | 142 | --- 143 | 144 | (ql 145 | (moduleMember 146 | (module 147 | (moduleName 148 | (simpleId)) 149 | (signatureExpr 150 | (typeExpr 151 | (className))) 152 | (moduleMember 153 | (classlessPredicate 154 | (typeExpr 155 | (primitiveType)) 156 | (predicateName) 157 | (body 158 | (comp_term 159 | (variable 160 | (result)) 161 | (compop) 162 | (literal 163 | (integer))))))))) 164 | 165 | ================================ 166 | parameterised module application 167 | ================================ 168 | 169 | select PModule::foo() 170 | 171 | --- 172 | 173 | 174 | (ql 175 | (moduleMember 176 | (select 177 | (asExprs 178 | (asExpr 179 | (call_or_unqual_agg_expr 180 | (aritylessPredicateExpr 181 | (moduleExpr 182 | (moduleInstantiation 183 | (moduleName 184 | (simpleId)) 185 | (signatureExpr 186 | (predicateExpr 187 | (aritylessPredicateExpr 188 | (literalId)) 189 | (integer))) 190 | (signatureExpr 191 | (predicateExpr 192 | (aritylessPredicateExpr 193 | (literalId)) 194 | (integer))) 195 | (signatureExpr 196 | (typeExpr 197 | (className))) 198 | (signatureExpr 199 | (typeExpr 200 | (className))))) 201 | (literalId)) 202 | (call_body))))))) 203 | 204 | ================== 205 | second application 206 | ================== 207 | 208 | where node = DataFlow::BarrierGuard::getABarrierNode() 209 | select 1 210 | 211 | --- 212 | 213 | (ql 214 | (moduleMember 215 | (select 216 | (comp_term 217 | (variable 218 | (varName 219 | (simpleId))) 220 | (compop) 221 | (call_or_unqual_agg_expr 222 | (aritylessPredicateExpr 223 | (moduleExpr 224 | (moduleExpr 225 | (simpleId)) 226 | (moduleInstantiation 227 | (moduleName 228 | (simpleId)) 229 | (signatureExpr 230 | (predicateExpr 231 | (aritylessPredicateExpr 232 | (literalId)) 233 | (integer))))) 234 | (literalId)) 235 | (call_body))) 236 | (asExprs 237 | (asExpr 238 | (literal 239 | (integer))))))) -------------------------------------------------------------------------------- /test/corpus/operators_and_precedence.txt: -------------------------------------------------------------------------------- 1 | ============ 2 | And vs Or 1 3 | ============ 4 | 5 | from Foo f 6 | where f = f and f = f or f = f 7 | select f 8 | 9 | --- 10 | 11 | (ql (moduleMember 12 | (select 13 | (varDecl (typeExpr (className)) (varName (simpleId))) 14 | (disjunction 15 | (conjunction 16 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 17 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))) 18 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))) 19 | (asExprs (asExpr (variable (varName (simpleId)))))))) 20 | 21 | ============ 22 | And vs Or 2 23 | ============ 24 | 25 | from Foo f 26 | where f = f or f = f and f = f 27 | select f 28 | 29 | --- 30 | 31 | (ql (moduleMember 32 | (select (varDecl (typeExpr (className)) (varName (simpleId))) 33 | (disjunction 34 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 35 | (conjunction 36 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 37 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))))) 38 | (asExprs (asExpr (variable (varName (simpleId)))))))) 39 | 40 | ============ 41 | Or vs implies 42 | ============ 43 | 44 | from Foo f 45 | where (f = f or f = f implies f = f) 46 | and (f = f implies f = f or f = f) 47 | select f 48 | 49 | --- 50 | 51 | (ql (moduleMember 52 | (select 53 | (varDecl (typeExpr (className)) (varName (simpleId))) 54 | (conjunction 55 | (par_expr 56 | (implication 57 | (disjunction 58 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 59 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))) 60 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))))) 61 | (par_expr 62 | (implication 63 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 64 | (disjunction 65 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 66 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))))))) 67 | (asExprs (asExpr (variable (varName (simpleId)))))))) 68 | 69 | ============ 70 | if then else 71 | ============ 72 | 73 | from Foo f 74 | where if f = f then f = f else f = f 75 | select f 76 | 77 | --- 78 | 79 | (ql (moduleMember 80 | (select 81 | (varDecl (typeExpr (className)) (varName (simpleId))) 82 | (if_term 83 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 84 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 85 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))) 86 | (asExprs (asExpr (variable (varName (simpleId)))))))) 87 | 88 | ========== 89 | and vs not 90 | ========== 91 | 92 | from Foo f 93 | where not f = f and f = f 94 | select f 95 | 96 | --- 97 | 98 | (ql (moduleMember 99 | (select 100 | (varDecl (typeExpr (className)) (varName (simpleId))) 101 | (conjunction 102 | (negation (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))) 103 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))) 104 | (asExprs (asExpr (variable (varName (simpleId)))))))) 105 | 106 | ========== 107 | call vs plus 108 | ========== 109 | 110 | select a+(b) 111 | 112 | --- 113 | 114 | (ql (moduleMember (select (asExprs (asExpr (call_or_unqual_agg_expr (aritylessPredicateExpr (literalId)) (closure) (call_body (variable (varName (simpleId)))))))))) 115 | 116 | ========== 117 | cast vs subtract 118 | ========== 119 | 120 | select (A)-(b) 121 | 122 | --- 123 | (ql (moduleMember (select (asExprs (asExpr (prefix_cast (typeExpr (className)) (unary_expr (unop) (par_expr (variable (varName (simpleId))))))))))) 124 | -------------------------------------------------------------------------------- /test/corpus/predicates.txt: -------------------------------------------------------------------------------- 1 | ======= 2 | no-body 3 | ======= 4 | 5 | predicate foo(); 6 | 7 | mod::Type foo(int arg, Foo arg); 8 | 9 | --- 10 | 11 | (ql 12 | (moduleMember (classlessPredicate (predicate) (predicateName) (empty))) 13 | (moduleMember (classlessPredicate (typeExpr (moduleExpr (simpleId)) (className)) (predicateName) 14 | (varDecl (typeExpr (primitiveType)) (varName (simpleId))) (varDecl (typeExpr (className)) (varName (simpleId))) (empty)))) 15 | 16 | ================ 17 | simple predicate 18 | ================ 19 | 20 | predicate foo(F f){ 21 | f = f 22 | } 23 | 24 | int predicateWithResult(){ 25 | result = 43 26 | } 27 | 28 | --- 29 | 30 | (ql 31 | (moduleMember (classlessPredicate (predicate) (predicateName) (varDecl (typeExpr (className)) (varName (simpleId))) (body 32 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))))) 33 | (moduleMember (classlessPredicate (typeExpr (primitiveType)) (predicateName) (body 34 | (comp_term (variable (result)) (compop) (literal (integer))))))) 35 | 36 | ===================== 37 | higher-order relation 38 | ===================== 39 | 40 | int foo(X x, Y y) = name(pred1/1, pred2/3)(x.x(), result) 41 | 42 | --- 43 | 44 | (ql (moduleMember 45 | (classlessPredicate 46 | (typeExpr (primitiveType)) 47 | (predicateName) 48 | (varDecl (typeExpr (className)) (varName (simpleId))) 49 | (varDecl (typeExpr (className)) (varName (simpleId))) 50 | (higherOrderTerm (literalId) 51 | (predicateExpr (aritylessPredicateExpr (literalId)) (integer)) 52 | (predicateExpr (aritylessPredicateExpr (literalId)) (integer)) 53 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) 54 | (variable (result)))))) 55 | 56 | =============== 57 | predicate alias 58 | =============== 59 | 60 | predicate foo = somePredicate/12; 61 | 62 | --- 63 | 64 | (ql (moduleMember (classlessPredicate 65 | (predicate) 66 | (predicateName) (predicateAliasBody (predicateExpr (aritylessPredicateExpr (literalId)) (integer)))))) 67 | 68 | ========== 69 | type union 70 | ========== 71 | 72 | newtype T = 73 | T1() or 74 | T2(int x) { x = 1 or x = 2 } or 75 | T3(int x) { x = 3 or x = 4 or x = 5 } 76 | 77 | class T2orT3 = T2 or T3; 78 | 79 | --- 80 | 81 | (ql (moduleMember (datatype (className) (datatypeBranches 82 | (datatypeBranch (className)) 83 | (datatypeBranch (className) (varDecl (typeExpr (primitiveType)) (varName (simpleId))) (body (disjunction 84 | (comp_term (variable (varName (simpleId))) (compop) (literal (integer))) 85 | (comp_term (variable (varName (simpleId))) (compop) (literal (integer)))))) 86 | (datatypeBranch (className) (varDecl (typeExpr (primitiveType)) (varName (simpleId))) (body (disjunction (disjunction 87 | (comp_term (variable (varName (simpleId))) (compop) (literal (integer))) 88 | (comp_term (variable (varName (simpleId))) (compop) (literal (integer)))) 89 | (comp_term (variable (varName (simpleId))) (compop) (literal (integer))))))))) 90 | (moduleMember (dataclass (className) (typeUnionBody (typeExpr (className)) (typeExpr (className)))))) 91 | -------------------------------------------------------------------------------- /test/corpus/primary.txt: -------------------------------------------------------------------------------- 1 | ====== 2 | eparen 3 | ====== 4 | 5 | select (f).getAThing() 6 | 7 | --- 8 | 9 | (ql (moduleMember (select (asExprs (asExpr (qualified_expr (par_expr (variable (varName (simpleId)))) (qualifiedRhs (predicateName)))))))) 10 | 11 | ===== 12 | super 13 | ===== 14 | 15 | select super.foo(), module::Foo.super.foo() 16 | 17 | --- 18 | 19 | (ql (moduleMember 20 | (select 21 | (asExprs 22 | (asExpr (qualified_expr (super_ref (super)) (qualifiedRhs (predicateName)))) 23 | (asExpr (qualified_expr (super_ref (typeExpr (moduleExpr (simpleId)) (className)) (super)) (qualifiedRhs (predicateName)))))))) 24 | 25 | ============ 26 | postfix cast 27 | ============ 28 | 29 | select f.(Foo).thing() 30 | 31 | --- 32 | 33 | (ql (moduleMember (select (asExprs (asExpr (qualified_expr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (typeExpr (className)))) (qualifiedRhs (predicateName)))))))) 34 | 35 | === 36 | any 37 | === 38 | 39 | select 40 | any(Foo f), 41 | any(Foo f | f = f), 42 | any(Foo f | | f.thing()), 43 | any(Foo f | f = f | f.thing()) 44 | 45 | --- 46 | 47 | (ql (moduleMember (select (asExprs 48 | (asExpr (aggregate (aggId) (full_aggregate_body (varDecl (typeExpr (className)) (varName (simpleId)))))) 49 | (asExpr (aggregate (aggId) (full_aggregate_body (varDecl (typeExpr (className)) (varName (simpleId))) 50 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId))))))) 51 | (asExpr (aggregate (aggId) 52 | (full_aggregate_body 53 | (varDecl (typeExpr (className)) (varName (simpleId))) 54 | (asExprs (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))))))) 55 | (asExpr (aggregate (aggId) (full_aggregate_body 56 | (varDecl (typeExpr (className)) 57 | (varName (simpleId))) 58 | (comp_term (variable (varName (simpleId))) (compop) (variable (varName (simpleId)))) 59 | (asExprs (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))))))))))) 60 | 61 | 62 | ===== 63 | range 64 | ===== 65 | 66 | select [0..10] 67 | 68 | --- 69 | 70 | (ql (moduleMember (select (asExprs (asExpr (range (literal (integer)) (literal (integer)))))))) 71 | 72 | ========== 73 | aggregates 74 | ========== 75 | 76 | select 77 | rank[123](Foo f), 78 | count(f.thing()), 79 | count(f.thing() as thing order by thing asc, thing desc), 80 | count(Foo f), 81 | count(f), 82 | count (| | f), 83 | count(), 84 | count(Foo f | f.thing() ), 85 | sum(Foo f | | f.x() ), 86 | sum(Foo f | | f.x() as x), 87 | sum(Foo f | | f.x() as x order by x), 88 | sum(Foo f | | f.x() as x order by x asc, f.y()), 89 | sum(Foo f | f.thing() | f.x() ) 90 | 91 | --- 92 | 93 | (ql (moduleMember (select (asExprs 94 | (asExpr (aggregate (aggId) (literal (integer)) 95 | (full_aggregate_body (varDecl (typeExpr (className)) (varName (simpleId)))))) 96 | (asExpr (aggregate (aggId) 97 | (expr_aggregate_body (asExprs (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))))))) 98 | (asExpr (aggregate (aggId) 99 | (expr_aggregate_body (asExprs 100 | (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) (varName (simpleId)))) 101 | (orderBys 102 | (orderBy (variable (varName (simpleId))) (direction)) 103 | (orderBy (variable (varName (simpleId))) (direction)))))) 104 | (asExpr (aggregate (aggId) (full_aggregate_body (varDecl (typeExpr (className)) (varName (simpleId)))))) 105 | (asExpr (aggregate (aggId) (expr_aggregate_body (asExprs (asExpr (variable (varName (simpleId)))))))) 106 | (asExpr (aggregate (aggId) (full_aggregate_body (asExprs (asExpr (variable (varName (simpleId)))))))) 107 | (asExpr (aggregate (aggId))) 108 | (asExpr (aggregate (aggId) 109 | (full_aggregate_body (varDecl (typeExpr (className)) (varName (simpleId))) 110 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))))) 111 | (asExpr (aggregate (aggId) 112 | (full_aggregate_body 113 | (varDecl (typeExpr (className)) 114 | (varName (simpleId))) 115 | (asExprs 116 | (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))))))) 117 | (asExpr (aggregate (aggId) 118 | (full_aggregate_body 119 | (varDecl (typeExpr (className)) (varName (simpleId))) 120 | (asExprs 121 | (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) (varName (simpleId))))))) 122 | (asExpr (aggregate (aggId) (full_aggregate_body 123 | (varDecl (typeExpr (className)) (varName (simpleId))) 124 | (asExprs 125 | (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) (varName (simpleId)))) 126 | (orderBys (orderBy (variable (varName (simpleId)))))))) 127 | (asExpr (aggregate (aggId) 128 | (full_aggregate_body (varDecl (typeExpr (className)) (varName (simpleId))) 129 | (asExprs (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) (varName (simpleId)))) 130 | (orderBys 131 | (orderBy (variable (varName (simpleId))) (direction)) 132 | (orderBy (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))))))) 133 | (asExpr (aggregate (aggId) (full_aggregate_body 134 | (varDecl (typeExpr (className)) (varName (simpleId))) 135 | (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName))) 136 | (asExprs (asExpr (qualified_expr (variable (varName (simpleId))) (qualifiedRhs (predicateName)))))))))))) 137 | -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammars": [ 3 | { 4 | "name": "ql", 5 | "camelcase": "QL", 6 | "scope": "source.ql", 7 | "path": ".", 8 | "file-types": [ 9 | "ql", 10 | "qll" 11 | ] 12 | } 13 | ], 14 | "metadata": { 15 | "version": "0.23.1", 16 | "license": "MIT", 17 | "description": "Semmle QL grammar for tree-sitter", 18 | "authors": [ 19 | { 20 | "name": "Sam Lanning", 21 | "email": "sam@samlanning.com" 22 | } 23 | ], 24 | "links": { 25 | "repository": "https://github.com/tree-sitter/tree-sitter-ql" 26 | } 27 | }, 28 | "bindings": { 29 | "c": true, 30 | "go": true, 31 | "node": true, 32 | "python": true, 33 | "rust": true, 34 | "swift": true 35 | } 36 | } 37 | --------------------------------------------------------------------------------