├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml ├── dependabot.yml └── 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-go.h │ └── tree-sitter-go.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_go │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed ├── rust │ ├── build.rs │ └── lib.rs └── swift │ ├── TreeSitterGo │ └── go.h │ └── TreeSitterGoTests │ └── TreeSitterGoTests.swift ├── eslint.config.mjs ├── examples ├── letter_test.go ├── no_newline_at_eof.go ├── proc.go └── value.go ├── 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 │ ├── declarations.txt │ ├── expressions.txt │ ├── literals.txt │ ├── source_files.txt │ ├── statements.txt │ └── types.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/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: tree-sitter 4 | patreon: # Replace with a single Patreon username 5 | open_collective: tree-sitter # Replace with a single Open Collective username 6 | ko_fi: amaanq 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | commit-message: 8 | prefix: "ci" 9 | -------------------------------------------------------------------------------- /.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 tree-sitter 36 | uses: tree-sitter/setup-action/cli@v2 37 | - name: Set up examples 38 | run: |- 39 | git clone https://github.com/golang/go examples/go --single-branch --depth=1 --filter=blob:none 40 | git clone https://github.com/moby/moby examples/moby --single-branch --depth=1 --filter=blob:none 41 | - name: Run tests 42 | uses: tree-sitter/parser-test-action@v2 43 | with: 44 | test-rust: true 45 | test-node: true 46 | test-python: true 47 | test-go: true 48 | test-swift: true 49 | - name: Parse examples 50 | id: examples 51 | continue-on-error: true 52 | uses: tree-sitter/parse-action@v4 53 | with: 54 | files: examples/**/*.go 55 | invalid-files: | 56 | examples/go/src/cmd/compile/internal/syntax/testdata/*.go 57 | examples/go/src/cmd/compile/internal/types2/testdata/local/issue47996.go 58 | examples/go/src/go/parser/testdata/issue42951/not_a_file.go/invalid.go 59 | examples/go/src/internal/types/testdata/**/*.go 60 | examples/go/test/bombad.go 61 | examples/go/test/const2.go 62 | examples/go/test/ddd1.go 63 | examples/go/test/fixedbugs/**/*.go 64 | examples/go/test/import5.go 65 | examples/go/test/makenew.go 66 | examples/go/test/method4.dir/prog.go 67 | examples/go/test/method7.go 68 | examples/go/test/slice3err.go 69 | examples/go/test/switch2.go 70 | examples/go/test/syntax/chan.go 71 | examples/go/test/syntax/chan1.go 72 | examples/go/test/syntax/ddd.go 73 | examples/go/test/syntax/else.go 74 | examples/go/test/syntax/if.go 75 | examples/go/test/syntax/import.go 76 | examples/go/test/syntax/initvar.go 77 | examples/go/test/syntax/semi*.go 78 | examples/go/test/syntax/vareq.go 79 | examples/go/test/syntax/vareq1.go 80 | examples/go/test/typeparam/issue*.go 81 | examples/moby/daemon/logger/journald/read_test.go 82 | - uses: actions/upload-artifact@v4 83 | if: steps.examples.outputs.failures != '' 84 | with: 85 | name: failures-${{matrix.os}} 86 | path: ${{steps.examples.outputs.failures}} 87 | -------------------------------------------------------------------------------- /.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-go 4 | VERSION "0.23.4" 5 | DESCRIPTION "Go grammar for tree-sitter" 6 | HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-go" 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-go src/parser.c) 28 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c) 29 | target_sources(tree-sitter-go PRIVATE src/scanner.c) 30 | endif() 31 | target_include_directories(tree-sitter-go PRIVATE src) 32 | 33 | target_compile_definitions(tree-sitter-go PRIVATE 34 | $<$:TREE_SITTER_REUSE_ALLOCATOR> 35 | $<$:TREE_SITTER_DEBUG>) 36 | 37 | set_target_properties(tree-sitter-go 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-go.pc.in 45 | "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-go.pc" @ONLY) 46 | 47 | include(GNUInstallDirs) 48 | 49 | install(FILES bindings/c/tree-sitter-go.h 50 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tree_sitter") 51 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-go.pc" 52 | DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig") 53 | install(TARGETS tree-sitter-go 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.2.1" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" 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.9" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 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-go" 85 | version = "0.23.4" 86 | dependencies = [ 87 | "cc", 88 | "tree-sitter", 89 | "tree-sitter-language", 90 | ] 91 | 92 | [[package]] 93 | name = "tree-sitter-language" 94 | version = "0.1.2" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "e8ddffe35a0e5eeeadf13ff7350af564c6e73993a24db62caee1822b185c2600" 97 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-go" 3 | description = "Go grammar for tree-sitter" 4 | version = "0.23.4" 5 | authors = [ 6 | "Max Brunsfeld ", 7 | "Amaan Qureshi ", 8 | ] 9 | license = "MIT" 10 | readme = "README.md" 11 | keywords = ["incremental", "parsing", "tree-sitter", "go"] 12 | categories = ["parsing", "text-editors"] 13 | repository = "https://github.com/tree-sitter/tree-sitter-go" 14 | edition = "2021" 15 | autoexamples = false 16 | 17 | build = "bindings/rust/build.rs" 18 | include = ["LICENSE", "bindings/rust/*", "grammar.js", "queries/*", "src/*", "tree-sitter.json"] 19 | 20 | [lib] 21 | path = "bindings/rust/lib.rs" 22 | 23 | [dependencies] 24 | tree-sitter-language = "0.1" 25 | 26 | [build-dependencies] 27 | cc = "1.1" 28 | 29 | [dev-dependencies] 30 | tree-sitter = "0.24" 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Max Brunsfeld 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-go 6 | HOMEPAGE_URL := https://github.com/tree-sitter/tree-sitter-go 7 | VERSION := 0.23.4 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: "TreeSitterGo", 6 | products: [ 7 | .library(name: "TreeSitterGo", targets: ["TreeSitterGo"]), 8 | ], 9 | dependencies: [ 10 | .package(url: "https://github.com/ChimeHQ/SwiftTreeSitter", from: "0.8.0"), 11 | ], 12 | targets: [ 13 | .target( 14 | name: "TreeSitterGo", 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: "TreeSitterGoTests", 28 | dependencies: [ 29 | "SwiftTreeSitter", 30 | "TreeSitterGo", 31 | ], 32 | path: "bindings/swift/TreeSitterGoTests" 33 | ) 34 | ], 35 | cLanguageStandard: .c11 36 | ) 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-go 2 | 3 | [![CI][ci]](https://github.com/tree-sitter/tree-sitter-go/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-go) 7 | [![npm][npm]](https://www.npmjs.com/package/tree-sitter-go) 8 | [![pypi][pypi]](https://pypi.org/project/tree-sitter-go) 9 | 10 | [Go](https://go.dev/ref/spec) grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter). 11 | 12 | [ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter/tree-sitter-go/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-go?logo=npm 16 | [crates]: https://img.shields.io/crates/v/tree-sitter-go?logo=rust 17 | [pypi]: https://img.shields.io/pypi/v/tree-sitter-go?logo=pypi&logoColor=ffd242 18 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_go_binding", 5 | "dependencies": [ 6 | " 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_go(); 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, "go"); 14 | auto language = Napi::External::New(env, tree_sitter_go()); 15 | language.TypeTag(&LANGUAGE_TYPE_TAG); 16 | exports["language"] = language; 17 | return exports; 18 | } 19 | 20 | NODE_API_MODULE(tree_sitter_go_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-go.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_go 4 | 5 | 6 | class TestLanguage(TestCase): 7 | def test_can_load_grammar(self): 8 | try: 9 | tree_sitter.Language(tree_sitter_go.language()) 10 | except Exception: 11 | self.fail("Error loading Go grammar") 12 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_go/__init__.py: -------------------------------------------------------------------------------- 1 | """Go 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_go/__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_go/binding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_go(void); 6 | 7 | static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 8 | return PyCapsule_New(tree_sitter_go(), "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_go/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tree-sitter/tree-sitter-go/5e73f476efafe5c768eda19bbe877f188ded6144/bindings/python/tree_sitter_go/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-go"); 15 | } 16 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides Go 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 | //! use tree_sitter::Parser; 8 | //! 9 | //! let code = r#" 10 | //! func add(a, b int) int { 11 | //! return a + b 12 | //! } 13 | //! "#; 14 | //! let mut parser = Parser::new(); 15 | //! let language = tree_sitter_go::LANGUAGE; 16 | //! parser 17 | //! .set_language(&language.into()) 18 | //! .expect("Error loading Go parser"); 19 | //! let tree = parser.parse(code, None).unwrap(); 20 | //! assert!(!tree.root_node().has_error()); 21 | //! ``` 22 | //! 23 | //! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html 24 | //! [tree-sitter]: https://tree-sitter.github.io/ 25 | 26 | use tree_sitter_language::LanguageFn; 27 | 28 | extern "C" { 29 | fn tree_sitter_go() -> *const (); 30 | } 31 | 32 | /// The tree-sitter [`LanguageFn`][LanguageFn] for this grammar. 33 | /// 34 | /// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html 35 | pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_go) }; 36 | 37 | /// The content of the [`node-types.json`][] file for this grammar. 38 | /// 39 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types 40 | pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); 41 | 42 | /// The syntax highlighting query for this language. 43 | pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); 44 | 45 | /// The symbol tagging query for this language. 46 | pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); 47 | 48 | #[cfg(test)] 49 | mod tests { 50 | #[test] 51 | fn test_can_load_grammar() { 52 | let mut parser = tree_sitter::Parser::new(); 53 | parser 54 | .set_language(&super::LANGUAGE.into()) 55 | .expect("Error loading Go parser"); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterGo/go.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_GO_H_ 2 | #define TREE_SITTER_GO_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_go(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_GO_H_ 17 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterGoTests/TreeSitterGoTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftTreeSitter 3 | import TreeSitterGo 4 | 5 | final class TreeSitterGoTests: XCTestCase { 6 | func testCanLoadGrammar() throws { 7 | let parser = Parser() 8 | let language = Language(language: tree_sitter_go()) 9 | XCTAssertNoThrow(try parser.setLanguage(language), 10 | "Error loading Go grammar") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import treesitter from 'eslint-config-treesitter'; 2 | 3 | export default [ 4 | ...treesitter, 5 | ]; 6 | -------------------------------------------------------------------------------- /examples/letter_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package unicode_test 6 | 7 | import ( 8 | "flag" 9 | "fmt" 10 | "runtime" 11 | "sort" 12 | "testing" 13 | . "unicode" 14 | ) 15 | 16 | var upperTest = []rune{ 17 | 0x41, 18 | 0xc0, 19 | 0xd8, 20 | 0x100, 21 | 0x139, 22 | 0x14a, 23 | 0x178, 24 | 0x181, 25 | 0x376, 26 | 0x3cf, 27 | 0x13bd, 28 | 0x1f2a, 29 | 0x2102, 30 | 0x2c00, 31 | 0x2c10, 32 | 0x2c20, 33 | 0xa650, 34 | 0xa722, 35 | 0xff3a, 36 | 0x10400, 37 | 0x1d400, 38 | 0x1d7ca, 39 | } 40 | 41 | var notupperTest = []rune{ 42 | 0x40, 43 | 0x5b, 44 | 0x61, 45 | 0x185, 46 | 0x1b0, 47 | 0x377, 48 | 0x387, 49 | 0x2150, 50 | 0xab7d, 51 | 0xffff, 52 | 0x10000, 53 | } 54 | 55 | var letterTest = []rune{ 56 | 0x41, 57 | 0x61, 58 | 0xaa, 59 | 0xba, 60 | 0xc8, 61 | 0xdb, 62 | 0xf9, 63 | 0x2ec, 64 | 0x535, 65 | 0x620, 66 | 0x6e6, 67 | 0x93d, 68 | 0xa15, 69 | 0xb99, 70 | 0xdc0, 71 | 0xedd, 72 | 0x1000, 73 | 0x1200, 74 | 0x1312, 75 | 0x1401, 76 | 0x1885, 77 | 0x2c00, 78 | 0xa800, 79 | 0xf900, 80 | 0xfa30, 81 | 0xffda, 82 | 0xffdc, 83 | 0x10000, 84 | 0x10300, 85 | 0x10400, 86 | 0x20000, 87 | 0x2f800, 88 | 0x2fa1d, 89 | } 90 | 91 | var notletterTest = []rune{ 92 | 0x20, 93 | 0x35, 94 | 0x375, 95 | 0x619, 96 | 0x700, 97 | 0xfffe, 98 | 0x1ffff, 99 | 0x10ffff, 100 | } 101 | 102 | // Contains all the special cased Latin-1 chars. 103 | var spaceTest = []rune{ 104 | 0x09, 105 | 0x0a, 106 | 0x0b, 107 | 0x0c, 108 | 0x0d, 109 | 0x20, 110 | 0x85, 111 | 0xA0, 112 | 0x2000, 113 | 0x3000, 114 | } 115 | 116 | type caseT struct { 117 | cas int 118 | in, out rune 119 | } 120 | 121 | var caseTest = []caseT{ 122 | // errors 123 | {-1, '\n', 0xFFFD}, 124 | {UpperCase, -1, -1}, 125 | {UpperCase, 1 << 30, 1 << 30}, 126 | 127 | // ASCII (special-cased so test carefully) 128 | {UpperCase, '\n', '\n'}, 129 | {UpperCase, 'a', 'A'}, 130 | {UpperCase, 'A', 'A'}, 131 | {UpperCase, '7', '7'}, 132 | {LowerCase, '\n', '\n'}, 133 | {LowerCase, 'a', 'a'}, 134 | {LowerCase, 'A', 'a'}, 135 | {LowerCase, '7', '7'}, 136 | {TitleCase, '\n', '\n'}, 137 | {TitleCase, 'a', 'A'}, 138 | {TitleCase, 'A', 'A'}, 139 | {TitleCase, '7', '7'}, 140 | 141 | // Latin-1: easy to read the tests! 142 | {UpperCase, 0x80, 0x80}, 143 | {UpperCase, 'Å', 'Å'}, 144 | {UpperCase, 'å', 'Å'}, 145 | {LowerCase, 0x80, 0x80}, 146 | {LowerCase, 'Å', 'å'}, 147 | {LowerCase, 'å', 'å'}, 148 | {TitleCase, 0x80, 0x80}, 149 | {TitleCase, 'Å', 'Å'}, 150 | {TitleCase, 'å', 'Å'}, 151 | 152 | // 0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049 153 | {UpperCase, 0x0131, 'I'}, 154 | {LowerCase, 0x0131, 0x0131}, 155 | {TitleCase, 0x0131, 'I'}, 156 | 157 | // 0133;LATIN SMALL LIGATURE IJ;Ll;0;L; 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132 158 | {UpperCase, 0x0133, 0x0132}, 159 | {LowerCase, 0x0133, 0x0133}, 160 | {TitleCase, 0x0133, 0x0132}, 161 | 162 | // 212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B; 163 | {UpperCase, 0x212A, 0x212A}, 164 | {LowerCase, 0x212A, 'k'}, 165 | {TitleCase, 0x212A, 0x212A}, 166 | 167 | // From an UpperLower sequence 168 | // A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641; 169 | {UpperCase, 0xA640, 0xA640}, 170 | {LowerCase, 0xA640, 0xA641}, 171 | {TitleCase, 0xA640, 0xA640}, 172 | // A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640 173 | {UpperCase, 0xA641, 0xA640}, 174 | {LowerCase, 0xA641, 0xA641}, 175 | {TitleCase, 0xA641, 0xA640}, 176 | // A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F; 177 | {UpperCase, 0xA64E, 0xA64E}, 178 | {LowerCase, 0xA64E, 0xA64F}, 179 | {TitleCase, 0xA64E, 0xA64E}, 180 | // A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E 181 | {UpperCase, 0xA65F, 0xA65E}, 182 | {LowerCase, 0xA65F, 0xA65F}, 183 | {TitleCase, 0xA65F, 0xA65E}, 184 | 185 | // From another UpperLower sequence 186 | // 0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A; 187 | {UpperCase, 0x0139, 0x0139}, 188 | {LowerCase, 0x0139, 0x013A}, 189 | {TitleCase, 0x0139, 0x0139}, 190 | // 013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L; 004C 00B7;;;;N;;;;0140; 191 | {UpperCase, 0x013f, 0x013f}, 192 | {LowerCase, 0x013f, 0x0140}, 193 | {TitleCase, 0x013f, 0x013f}, 194 | // 0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147 195 | {UpperCase, 0x0148, 0x0147}, 196 | {LowerCase, 0x0148, 0x0148}, 197 | {TitleCase, 0x0148, 0x0147}, 198 | 199 | // Lowercase lower than uppercase. 200 | // AB78;CHEROKEE SMALL LETTER GE;Ll;0;L;;;;;N;;;13A8;;13A8 201 | {UpperCase, 0xab78, 0x13a8}, 202 | {LowerCase, 0xab78, 0xab78}, 203 | {TitleCase, 0xab78, 0x13a8}, 204 | {UpperCase, 0x13a8, 0x13a8}, 205 | {LowerCase, 0x13a8, 0xab78}, 206 | {TitleCase, 0x13a8, 0x13a8}, 207 | 208 | // Last block in the 5.1.0 table 209 | // 10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428; 210 | {UpperCase, 0x10400, 0x10400}, 211 | {LowerCase, 0x10400, 0x10428}, 212 | {TitleCase, 0x10400, 0x10400}, 213 | // 10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F; 214 | {UpperCase, 0x10427, 0x10427}, 215 | {LowerCase, 0x10427, 0x1044F}, 216 | {TitleCase, 0x10427, 0x10427}, 217 | // 10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400 218 | {UpperCase, 0x10428, 0x10400}, 219 | {LowerCase, 0x10428, 0x10428}, 220 | {TitleCase, 0x10428, 0x10400}, 221 | // 1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427 222 | {UpperCase, 0x1044F, 0x10427}, 223 | {LowerCase, 0x1044F, 0x1044F}, 224 | {TitleCase, 0x1044F, 0x10427}, 225 | 226 | // First one not in the 5.1.0 table 227 | // 10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;; 228 | {UpperCase, 0x10450, 0x10450}, 229 | {LowerCase, 0x10450, 0x10450}, 230 | {TitleCase, 0x10450, 0x10450}, 231 | 232 | // Non-letters with case. 233 | {LowerCase, 0x2161, 0x2171}, 234 | {UpperCase, 0x0345, 0x0399}, 235 | } 236 | 237 | func TestIsLetter(t *testing.T) { 238 | for _, r := range upperTest { 239 | if !IsLetter(r) { 240 | t.Errorf("IsLetter(U+%04X) = false, want true", r) 241 | } 242 | } 243 | for _, r := range letterTest { 244 | if !IsLetter(r) { 245 | t.Errorf("IsLetter(U+%04X) = false, want true", r) 246 | } 247 | } 248 | for _, r := range notletterTest { 249 | if IsLetter(r) { 250 | t.Errorf("IsLetter(U+%04X) = true, want false", r) 251 | } 252 | } 253 | } 254 | 255 | func TestIsUpper(t *testing.T) { 256 | for _, r := range upperTest { 257 | if !IsUpper(r) { 258 | t.Errorf("IsUpper(U+%04X) = false, want true", r) 259 | } 260 | } 261 | for _, r := range notupperTest { 262 | if IsUpper(r) { 263 | t.Errorf("IsUpper(U+%04X) = true, want false", r) 264 | } 265 | } 266 | for _, r := range notletterTest { 267 | if IsUpper(r) { 268 | t.Errorf("IsUpper(U+%04X) = true, want false", r) 269 | } 270 | } 271 | } 272 | 273 | func caseString(c int) string { 274 | switch c { 275 | case UpperCase: 276 | return "UpperCase" 277 | case LowerCase: 278 | return "LowerCase" 279 | case TitleCase: 280 | return "TitleCase" 281 | } 282 | return "ErrorCase" 283 | } 284 | 285 | func TestTo(t *testing.T) { 286 | for _, c := range caseTest { 287 | r := To(c.cas, c.in) 288 | if c.out != r { 289 | t.Errorf("To(U+%04X, %s) = U+%04X want U+%04X", c.in, caseString(c.cas), r, c.out) 290 | } 291 | } 292 | } 293 | 294 | func TestToUpperCase(t *testing.T) { 295 | for _, c := range caseTest { 296 | if c.cas != UpperCase { 297 | continue 298 | } 299 | r := ToUpper(c.in) 300 | if c.out != r { 301 | t.Errorf("ToUpper(U+%04X) = U+%04X want U+%04X", c.in, r, c.out) 302 | } 303 | } 304 | } 305 | 306 | func TestToLowerCase(t *testing.T) { 307 | for _, c := range caseTest { 308 | if c.cas != LowerCase { 309 | continue 310 | } 311 | r := ToLower(c.in) 312 | if c.out != r { 313 | t.Errorf("ToLower(U+%04X) = U+%04X want U+%04X", c.in, r, c.out) 314 | } 315 | } 316 | } 317 | 318 | func TestToTitleCase(t *testing.T) { 319 | for _, c := range caseTest { 320 | if c.cas != TitleCase { 321 | continue 322 | } 323 | r := ToTitle(c.in) 324 | if c.out != r { 325 | t.Errorf("ToTitle(U+%04X) = U+%04X want U+%04X", c.in, r, c.out) 326 | } 327 | } 328 | } 329 | 330 | func TestIsSpace(t *testing.T) { 331 | for _, c := range spaceTest { 332 | if !IsSpace(c) { 333 | t.Errorf("IsSpace(U+%04X) = false; want true", c) 334 | } 335 | } 336 | for _, c := range letterTest { 337 | if IsSpace(c) { 338 | t.Errorf("IsSpace(U+%04X) = true; want false", c) 339 | } 340 | } 341 | } 342 | 343 | // Check that the optimizations for IsLetter etc. agree with the tables. 344 | // We only need to check the Latin-1 range. 345 | func TestLetterOptimizations(t *testing.T) { 346 | for i := rune(0); i <= MaxLatin1; i++ { 347 | if Is(Letter, i) != IsLetter(i) { 348 | t.Errorf("IsLetter(U+%04X) disagrees with Is(Letter)", i) 349 | } 350 | if Is(Upper, i) != IsUpper(i) { 351 | t.Errorf("IsUpper(U+%04X) disagrees with Is(Upper)", i) 352 | } 353 | if Is(Lower, i) != IsLower(i) { 354 | t.Errorf("IsLower(U+%04X) disagrees with Is(Lower)", i) 355 | } 356 | if Is(Title, i) != IsTitle(i) { 357 | t.Errorf("IsTitle(U+%04X) disagrees with Is(Title)", i) 358 | } 359 | if Is(White_Space, i) != IsSpace(i) { 360 | t.Errorf("IsSpace(U+%04X) disagrees with Is(White_Space)", i) 361 | } 362 | if To(UpperCase, i) != ToUpper(i) { 363 | t.Errorf("ToUpper(U+%04X) disagrees with To(Upper)", i) 364 | } 365 | if To(LowerCase, i) != ToLower(i) { 366 | t.Errorf("ToLower(U+%04X) disagrees with To(Lower)", i) 367 | } 368 | if To(TitleCase, i) != ToTitle(i) { 369 | t.Errorf("ToTitle(U+%04X) disagrees with To(Title)", i) 370 | } 371 | } 372 | } 373 | 374 | func TestTurkishCase(t *testing.T) { 375 | lower := []rune("abcçdefgğhıijklmnoöprsştuüvyz") 376 | upper := []rune("ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ") 377 | for i, l := range lower { 378 | u := upper[i] 379 | if TurkishCase.ToLower(l) != l { 380 | t.Errorf("lower(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToLower(l), l) 381 | } 382 | if TurkishCase.ToUpper(u) != u { 383 | t.Errorf("upper(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToUpper(u), u) 384 | } 385 | if TurkishCase.ToUpper(l) != u { 386 | t.Errorf("upper(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToUpper(l), u) 387 | } 388 | if TurkishCase.ToLower(u) != l { 389 | t.Errorf("lower(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToLower(l), l) 390 | } 391 | if TurkishCase.ToTitle(u) != u { 392 | t.Errorf("title(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToTitle(u), u) 393 | } 394 | if TurkishCase.ToTitle(l) != u { 395 | t.Errorf("title(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToTitle(l), u) 396 | } 397 | } 398 | } 399 | 400 | var simpleFoldTests = []string{ 401 | // SimpleFold(x) returns the next equivalent rune > x or wraps 402 | // around to smaller values. 403 | 404 | // Easy cases. 405 | "Aa", 406 | "δΔ", 407 | 408 | // ASCII special cases. 409 | "KkK", 410 | "Ssſ", 411 | 412 | // Non-ASCII special cases. 413 | "ρϱΡ", 414 | "ͅΙιι", 415 | 416 | // Extra special cases: has lower/upper but no case fold. 417 | "İ", 418 | "ı", 419 | 420 | // Upper comes before lower (Cherokee). 421 | "\u13b0\uab80", 422 | } 423 | 424 | func TestSimpleFold(t *testing.T) { 425 | for _, tt := range simpleFoldTests { 426 | cycle := []rune(tt) 427 | r := cycle[len(cycle)-1] 428 | for _, out := range cycle { 429 | if r := SimpleFold(r); r != out { 430 | t.Errorf("SimpleFold(%#U) = %#U, want %#U", r, r, out) 431 | } 432 | r = out 433 | } 434 | } 435 | } 436 | 437 | // Running 'go test -calibrate' runs the calibration to find a plausible 438 | // cutoff point for linear search of a range list vs. binary search. 439 | // We create a fake table and then time how long it takes to do a 440 | // sequence of searches within that table, for all possible inputs 441 | // relative to the ranges (something before all, in each, between each, after all). 442 | // This assumes that all possible runes are equally likely. 443 | // In practice most runes are ASCII so this is a conservative estimate 444 | // of an effective cutoff value. In practice we could probably set it higher 445 | // than what this function recommends. 446 | 447 | var calibrate = flag.Bool("calibrate", false, "compute crossover for linear vs. binary search") 448 | 449 | func TestCalibrate(t *testing.T) { 450 | if !*calibrate { 451 | return 452 | } 453 | 454 | if runtime.GOARCH == "amd64" { 455 | fmt.Printf("warning: running calibration on %s\n", runtime.GOARCH) 456 | } 457 | 458 | // Find the point where binary search wins by more than 10%. 459 | // The 10% bias gives linear search an edge when they're close, 460 | // because on predominantly ASCII inputs linear search is even 461 | // better than our benchmarks measure. 462 | n := sort.Search(64, func(n int) bool { 463 | tab := fakeTable(n) 464 | blinear := func(b *testing.B) { 465 | tab := tab 466 | max := n*5 + 20 467 | for i := 0; i < b.N; i++ { 468 | for j := 0; j <= max; j++ { 469 | linear(tab, uint16(j)) 470 | } 471 | } 472 | } 473 | bbinary := func(b *testing.B) { 474 | tab := tab 475 | max := n*5 + 20 476 | for i := 0; i < b.N; i++ { 477 | for j := 0; j <= max; j++ { 478 | binary(tab, uint16(j)) 479 | } 480 | } 481 | } 482 | bmlinear := testing.Benchmark(blinear) 483 | bmbinary := testing.Benchmark(bbinary) 484 | fmt.Printf("n=%d: linear=%d binary=%d\n", n, bmlinear.NsPerOp(), bmbinary.NsPerOp()) 485 | return bmlinear.NsPerOp()*100 > bmbinary.NsPerOp()*110 486 | }) 487 | fmt.Printf("calibration: linear cutoff = %d\n", n) 488 | } 489 | 490 | func fakeTable(n int) []Range16 { 491 | var r16 []Range16 492 | for i := 0; i < n; i++ { 493 | r16 = append(r16, Range16{uint16(i*5 + 10), uint16(i*5 + 12), 1}) 494 | } 495 | return r16 496 | } 497 | 498 | func linear(ranges []Range16, r uint16) bool { 499 | for i := range ranges { 500 | range_ := &ranges[i] 501 | if r < range_.Lo { 502 | return false 503 | } 504 | if r <= range_.Hi { 505 | return (r-range_.Lo)%range_.Stride == 0 506 | } 507 | } 508 | return false 509 | } 510 | 511 | func binary(ranges []Range16, r uint16) bool { 512 | // binary search over ranges 513 | lo := 0 514 | hi := len(ranges) 515 | for lo < hi { 516 | m := lo + (hi-lo)/2 517 | range_ := &ranges[m] 518 | if range_.Lo <= r && r <= range_.Hi { 519 | return (r-range_.Lo)%range_.Stride == 0 520 | } 521 | if r < range_.Lo { 522 | hi = m 523 | } else { 524 | lo = m + 1 525 | } 526 | } 527 | return false 528 | } 529 | 530 | func TestLatinOffset(t *testing.T) { 531 | var maps = []map[string]*RangeTable{ 532 | Categories, 533 | FoldCategory, 534 | FoldScript, 535 | Properties, 536 | Scripts, 537 | } 538 | for _, m := range maps { 539 | for name, tab := range m { 540 | i := 0 541 | for i < len(tab.R16) && tab.R16[i].Hi <= MaxLatin1 { 542 | i++ 543 | } 544 | if tab.LatinOffset != i { 545 | t.Errorf("%s: LatinOffset=%d, want %d", name, tab.LatinOffset, i) 546 | } 547 | } 548 | } 549 | } 550 | -------------------------------------------------------------------------------- /examples/no_newline_at_eof.go: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | // Copyright 2015 The Go Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style 5 | // license that can be found in the LICENSE file. 6 | 7 | package main 8 | 9 | func main() { 10 | x := 0 11 | func() { 12 | x = 1 13 | }() 14 | func() { 15 | if x != 1 { 16 | panic("x != 1") 17 | } 18 | }() 19 | } -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tree-sitter/tree-sitter-go 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-html v0.20.5-0.20240818004741-d11201a263d0 h1:c46K6uh5Dz00zJeU9BfjXdb8I+E4RkUdfnWJpQADXFo= 18 | github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0/go.mod h1:hcNt/kOJHcIcuMvouE7LJcYdeFUFbVpBJ6d4wmOA+tU= 19 | github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495 h1:jrt4qbJVEFs4H93/ITxygHc6u0TGqAkkate7TQ4wFSA= 20 | github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495/go.mod h1:oyaR7fLnRV0hT9z6qwE9GkaeTom/hTDwK3H2idcOJFc= 21 | github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5 h1:om4X9AVg3asL8gxNJDcz4e/Wp+VpQj1PY3uJXKr6EOg= 22 | github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5/go.mod h1:nNqgPoV/h9uYWk6kYEFdEAhNVOacpfpRW5SFmdaP4tU= 23 | github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5 h1:pfV3G3k7NCKqKk8THBmyuh2zA33lgYHS3GVrzRR8ry4= 24 | github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5/go.mod h1:GbMKRjLfk0H+PI7nLi1Sx5lHf5wCpLz9al8tQYSxpEk= 25 | github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1 h1:ZXZMDwE+IhUtGug4Brv6NjJWUU3rfkZBKpemf6RY8/g= 26 | github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1/go.mod h1:UKCLuYnJ312Mei+3cyTmGOHzn0YAnaPRECgJmHtzrqs= 27 | github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb h1:EXEM82lFM7JjJb6qiKZXkpIDaCcbV2obNn82ghwj9lw= 28 | github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb/go.mod h1:lXCF1nGG5Dr4J3BTS0ObN4xJCCICiSu/b+Xe/VqMV7g= 29 | github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d h1:fcYCvoXdcP1uRQYXqJHRy6Hec+uKScQdKVtMwK9JeCI= 30 | github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d/go.mod h1:T1nShQ4v5AJtozZ8YyAS4uzUtDAJj/iv4YfwXSbUHzg= 31 | github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447 h1:o9alBu1J/WjrcTKEthYtXmdkDc5OVXD+PqlvnEZ0Lzc= 32 | github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447/go.mod h1:1Oh95COkkTn6Ezp0vcMbvfhRP5gLeqqljR0BYnBzWvc= 33 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 34 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 35 | -------------------------------------------------------------------------------- /grammar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Go grammar for tree-sitter 3 | * @author Max Brunsfeld 4 | * @author Amaan Qureshi 5 | * @license MIT 6 | */ 7 | 8 | /// 9 | // @ts-check 10 | 11 | const PREC = { 12 | primary: 7, 13 | unary: 6, 14 | multiplicative: 5, 15 | additive: 4, 16 | comparative: 3, 17 | and: 2, 18 | or: 1, 19 | composite_literal: -1, 20 | }; 21 | 22 | const multiplicativeOperators = ['*', '/', '%', '<<', '>>', '&', '&^']; 23 | const additiveOperators = ['+', '-', '|', '^']; 24 | const comparativeOperators = ['==', '!=', '<', '<=', '>', '>=']; 25 | const assignmentOperators = multiplicativeOperators.concat(additiveOperators).map(operator => operator + '=').concat('='); 26 | 27 | 28 | const newline = /\n/; 29 | const terminator = choice(newline, ';', '\0'); 30 | 31 | const hexDigit = /[0-9a-fA-F]/; 32 | const octalDigit = /[0-7]/; 33 | const decimalDigit = /[0-9]/; 34 | const binaryDigit = /[01]/; 35 | 36 | const hexDigits = seq(hexDigit, repeat(seq(optional('_'), hexDigit))); 37 | const octalDigits = seq(octalDigit, repeat(seq(optional('_'), octalDigit))); 38 | const decimalDigits = seq(decimalDigit, repeat(seq(optional('_'), decimalDigit))); 39 | const binaryDigits = seq(binaryDigit, repeat(seq(optional('_'), binaryDigit))); 40 | 41 | const hexLiteral = seq('0', choice('x', 'X'), optional('_'), hexDigits); 42 | const octalLiteral = seq('0', optional(choice('o', 'O')), optional('_'), octalDigits); 43 | const decimalLiteral = choice('0', seq(/[1-9]/, optional(seq(optional('_'), decimalDigits)))); 44 | const binaryLiteral = seq('0', choice('b', 'B'), optional('_'), binaryDigits); 45 | 46 | const intLiteral = choice(binaryLiteral, decimalLiteral, octalLiteral, hexLiteral); 47 | 48 | const decimalExponent = seq(choice('e', 'E'), optional(choice('+', '-')), decimalDigits); 49 | const decimalFloatLiteral = choice( 50 | seq(decimalDigits, '.', optional(decimalDigits), optional(decimalExponent)), 51 | seq(decimalDigits, decimalExponent), 52 | seq('.', decimalDigits, optional(decimalExponent)), 53 | ); 54 | 55 | const hexExponent = seq(choice('p', 'P'), optional(choice('+', '-')), decimalDigits); 56 | const hexMantissa = choice( 57 | seq(optional('_'), hexDigits, '.', optional(hexDigits)), 58 | seq(optional('_'), hexDigits), 59 | seq('.', hexDigits), 60 | ); 61 | const hexFloatLiteral = seq('0', choice('x', 'X'), hexMantissa, hexExponent); 62 | 63 | const floatLiteral = choice(decimalFloatLiteral, hexFloatLiteral); 64 | 65 | const imaginaryLiteral = seq(choice(decimalDigits, intLiteral, floatLiteral), 'i'); 66 | 67 | module.exports = grammar({ 68 | name: 'go', 69 | 70 | extras: $ => [ 71 | $.comment, 72 | /\s/, 73 | ], 74 | 75 | inline: $ => [ 76 | $._type, 77 | $._type_identifier, 78 | $._field_identifier, 79 | $._package_identifier, 80 | $._top_level_declaration, 81 | $._string_literal, 82 | $._interface_elem, 83 | ], 84 | 85 | word: $ => $.identifier, 86 | 87 | conflicts: $ => [ 88 | [$._simple_type, $._expression], 89 | [$._simple_type, $.generic_type, $._expression], 90 | [$.qualified_type, $._expression], 91 | [$.generic_type, $._simple_type], 92 | [$.parameter_declaration, $._simple_type], 93 | [$.type_parameter_declaration, $._simple_type, $._expression], 94 | [$.type_parameter_declaration, $._expression], 95 | [$.type_parameter_declaration, $._simple_type, $.generic_type, $._expression], 96 | ], 97 | 98 | supertypes: $ => [ 99 | $._expression, 100 | $._type, 101 | $._simple_type, 102 | $._statement, 103 | $._simple_statement, 104 | ], 105 | 106 | rules: { 107 | source_file: $ => seq( 108 | repeat(choice( 109 | // Unlike a Go compiler, we accept statements at top-level to enable 110 | // parsing of partial code snippets in documentation (see #63). 111 | seq($._statement, terminator), 112 | seq($._top_level_declaration, terminator), 113 | )), 114 | optional($._top_level_declaration), 115 | ), 116 | 117 | _top_level_declaration: $ => choice( 118 | $.package_clause, 119 | $.function_declaration, 120 | $.method_declaration, 121 | $.import_declaration, 122 | ), 123 | 124 | package_clause: $ => seq( 125 | 'package', 126 | $._package_identifier, 127 | ), 128 | 129 | import_declaration: $ => seq( 130 | 'import', 131 | choice( 132 | $.import_spec, 133 | $.import_spec_list, 134 | ), 135 | ), 136 | 137 | import_spec: $ => seq( 138 | optional(field('name', choice( 139 | $.dot, 140 | $.blank_identifier, 141 | $._package_identifier, 142 | ))), 143 | field('path', $._string_literal), 144 | ), 145 | dot: _ => '.', 146 | blank_identifier: _ => '_', 147 | 148 | import_spec_list: $ => seq( 149 | '(', 150 | optional(seq( 151 | $.import_spec, 152 | repeat(seq(terminator, $.import_spec)), 153 | optional(terminator), 154 | )), 155 | ')', 156 | ), 157 | 158 | _declaration: $ => choice( 159 | $.const_declaration, 160 | $.type_declaration, 161 | $.var_declaration, 162 | ), 163 | 164 | const_declaration: $ => seq( 165 | 'const', 166 | choice( 167 | $.const_spec, 168 | seq( 169 | '(', 170 | repeat(seq($.const_spec, terminator)), 171 | ')', 172 | ), 173 | ), 174 | ), 175 | 176 | const_spec: $ => prec.left(seq( 177 | field('name', commaSep1($.identifier)), 178 | optional(seq( 179 | optional(field('type', $._type)), 180 | '=', 181 | field('value', $.expression_list), 182 | )), 183 | )), 184 | 185 | var_declaration: $ => seq( 186 | 'var', 187 | choice( 188 | $.var_spec, 189 | $.var_spec_list, 190 | ), 191 | ), 192 | 193 | var_spec: $ => seq( 194 | commaSep1(field('name', $.identifier)), 195 | choice( 196 | seq( 197 | field('type', $._type), 198 | optional(seq('=', field('value', $.expression_list))), 199 | ), 200 | seq('=', field('value', $.expression_list)), 201 | ), 202 | ), 203 | 204 | var_spec_list: $ => seq( 205 | '(', 206 | repeat(seq($.var_spec, terminator)), 207 | ')', 208 | ), 209 | 210 | function_declaration: $ => prec.right(1, seq( 211 | 'func', 212 | field('name', $.identifier), 213 | field('type_parameters', optional($.type_parameter_list)), 214 | field('parameters', $.parameter_list), 215 | field('result', optional(choice($.parameter_list, $._simple_type))), 216 | field('body', optional($.block)), 217 | )), 218 | 219 | method_declaration: $ => prec.right(1, seq( 220 | 'func', 221 | field('receiver', $.parameter_list), 222 | field('name', $._field_identifier), 223 | field('parameters', $.parameter_list), 224 | field('result', optional(choice($.parameter_list, $._simple_type))), 225 | field('body', optional($.block)), 226 | )), 227 | 228 | type_parameter_list: $ => seq( 229 | '[', 230 | commaSep1($.type_parameter_declaration), 231 | optional(','), 232 | ']', 233 | ), 234 | 235 | type_parameter_declaration: $ => seq( 236 | commaSep1(field('name', $.identifier)), 237 | field('type', alias($.type_elem, $.type_constraint)), 238 | ), 239 | 240 | parameter_list: $ => seq( 241 | '(', 242 | optional(seq( 243 | commaSep(choice($.parameter_declaration, $.variadic_parameter_declaration)), 244 | optional(','), 245 | )), 246 | ')', 247 | ), 248 | 249 | parameter_declaration: $ => seq( 250 | commaSep(field('name', $.identifier)), 251 | field('type', $._type), 252 | ), 253 | 254 | variadic_parameter_declaration: $ => seq( 255 | field('name', optional($.identifier)), 256 | '...', 257 | field('type', $._type), 258 | ), 259 | 260 | type_alias: $ => seq( 261 | field('name', $._type_identifier), 262 | '=', 263 | field('type', $._type), 264 | ), 265 | 266 | type_declaration: $ => seq( 267 | 'type', 268 | choice( 269 | $.type_spec, 270 | $.type_alias, 271 | seq( 272 | '(', 273 | repeat(seq(choice($.type_spec, $.type_alias), terminator)), 274 | ')', 275 | ), 276 | ), 277 | ), 278 | 279 | type_spec: $ => seq( 280 | field('name', $._type_identifier), 281 | field('type_parameters', optional($.type_parameter_list)), 282 | field('type', $._type), 283 | ), 284 | 285 | field_name_list: $ => commaSep1($._field_identifier), 286 | 287 | expression_list: $ => commaSep1($._expression), 288 | 289 | _type: $ => choice( 290 | $._simple_type, 291 | $.parenthesized_type, 292 | ), 293 | 294 | parenthesized_type: $ => seq('(', $._type, ')'), 295 | 296 | _simple_type: $ => choice( 297 | prec.dynamic(-1, $._type_identifier), 298 | $.generic_type, 299 | $.qualified_type, 300 | $.pointer_type, 301 | $.struct_type, 302 | $.interface_type, 303 | $.array_type, 304 | $.slice_type, 305 | prec.dynamic(3, $.map_type), 306 | $.channel_type, 307 | $.function_type, 308 | $.negated_type, 309 | ), 310 | 311 | generic_type: $ => prec.dynamic(1, seq( 312 | field('type', choice($._type_identifier, $.qualified_type, $.negated_type)), 313 | field('type_arguments', $.type_arguments), 314 | )), 315 | 316 | type_arguments: $ => prec.dynamic(2, seq( 317 | '[', 318 | commaSep1($.type_elem), 319 | optional(','), 320 | ']', 321 | )), 322 | 323 | pointer_type: $ => prec(PREC.unary, seq('*', $._type)), 324 | 325 | array_type: $ => prec.right(seq( 326 | '[', 327 | field('length', $._expression), 328 | ']', 329 | field('element', $._type), 330 | )), 331 | 332 | implicit_length_array_type: $ => seq( 333 | '[', 334 | '...', 335 | ']', 336 | field('element', $._type), 337 | ), 338 | 339 | slice_type: $ => prec.right(seq( 340 | '[', 341 | ']', 342 | field('element', $._type), 343 | )), 344 | 345 | struct_type: $ => seq( 346 | 'struct', 347 | $.field_declaration_list, 348 | ), 349 | 350 | negated_type: $ => prec.left(seq( 351 | '~', 352 | $._type, 353 | )), 354 | 355 | field_declaration_list: $ => seq( 356 | '{', 357 | optional(seq( 358 | $.field_declaration, 359 | repeat(seq(terminator, $.field_declaration)), 360 | optional(terminator), 361 | )), 362 | '}', 363 | ), 364 | 365 | field_declaration: $ => seq( 366 | choice( 367 | seq( 368 | commaSep1(field('name', $._field_identifier)), 369 | field('type', $._type), 370 | ), 371 | seq( 372 | optional('*'), 373 | field('type', choice( 374 | $._type_identifier, 375 | $.qualified_type, 376 | $.generic_type, 377 | )), 378 | ), 379 | ), 380 | field('tag', optional($._string_literal)), 381 | ), 382 | 383 | interface_type: $ => seq( 384 | 'interface', 385 | '{', 386 | optional(seq( 387 | $._interface_elem, 388 | repeat(seq(terminator, $._interface_elem)), 389 | optional(terminator), 390 | )), 391 | '}', 392 | ), 393 | 394 | _interface_elem: $ => choice( 395 | $.method_elem, 396 | $.type_elem, 397 | ), 398 | 399 | method_elem: $ => seq( 400 | field('name', $._field_identifier), 401 | field('parameters', $.parameter_list), 402 | field('result', optional(choice($.parameter_list, $._simple_type))), 403 | ), 404 | 405 | type_elem: $ => sep1($._type, '|'), 406 | 407 | map_type: $ => prec.right(seq( 408 | 'map', 409 | '[', 410 | field('key', $._type), 411 | ']', 412 | field('value', $._type), 413 | )), 414 | 415 | channel_type: $ => prec.left(choice( 416 | seq('chan', field('value', $._type)), 417 | seq('chan', '<-', field('value', $._type)), 418 | prec(PREC.unary, seq('<-', 'chan', field('value', $._type))), 419 | )), 420 | 421 | function_type: $ => prec.right(seq( 422 | 'func', 423 | field('parameters', $.parameter_list), 424 | field('result', optional(choice($.parameter_list, $._simple_type))), 425 | )), 426 | 427 | block: $ => seq( 428 | '{', 429 | optional($._statement_list), 430 | '}', 431 | ), 432 | 433 | _statement_list: $ => choice( 434 | seq( 435 | $._statement, 436 | repeat(seq(terminator, $._statement)), 437 | optional(seq( 438 | terminator, 439 | optional(alias($.empty_labeled_statement, $.labeled_statement)), 440 | )), 441 | ), 442 | alias($.empty_labeled_statement, $.labeled_statement), 443 | ), 444 | 445 | _statement: $ => choice( 446 | $._declaration, 447 | $._simple_statement, 448 | $.return_statement, 449 | $.go_statement, 450 | $.defer_statement, 451 | $.if_statement, 452 | $.for_statement, 453 | $.expression_switch_statement, 454 | $.type_switch_statement, 455 | $.select_statement, 456 | $.labeled_statement, 457 | $.fallthrough_statement, 458 | $.break_statement, 459 | $.continue_statement, 460 | $.goto_statement, 461 | $.block, 462 | $.empty_statement, 463 | ), 464 | 465 | empty_statement: _ => ';', 466 | 467 | _simple_statement: $ => choice( 468 | $.expression_statement, 469 | $.send_statement, 470 | $.inc_statement, 471 | $.dec_statement, 472 | $.assignment_statement, 473 | $.short_var_declaration, 474 | ), 475 | 476 | expression_statement: $ => $._expression, 477 | 478 | send_statement: $ => seq( 479 | field('channel', $._expression), 480 | '<-', 481 | field('value', $._expression), 482 | ), 483 | 484 | receive_statement: $ => seq( 485 | optional(seq( 486 | field('left', $.expression_list), 487 | choice('=', ':='), 488 | )), 489 | field('right', $._expression), 490 | ), 491 | 492 | inc_statement: $ => seq( 493 | $._expression, 494 | '++', 495 | ), 496 | 497 | dec_statement: $ => seq( 498 | $._expression, 499 | '--', 500 | ), 501 | 502 | assignment_statement: $ => seq( 503 | field('left', $.expression_list), 504 | field('operator', choice(...assignmentOperators)), 505 | field('right', $.expression_list), 506 | ), 507 | 508 | short_var_declaration: $ => seq( 509 | // TODO: this should really only allow identifier lists, but that causes 510 | // conflicts between identifiers as expressions vs identifiers here. 511 | field('left', $.expression_list), 512 | ':=', 513 | field('right', $.expression_list), 514 | ), 515 | 516 | labeled_statement: $ => seq( 517 | field('label', alias($.identifier, $.label_name)), 518 | ':', 519 | $._statement, 520 | ), 521 | 522 | empty_labeled_statement: $ => seq( 523 | field('label', alias($.identifier, $.label_name)), 524 | ':', 525 | ), 526 | 527 | // This is a hack to prevent `fallthrough_statement` from being parsed as 528 | // a single token. For consistency with `break_statement` etc it should 529 | // be parsed as a parent node that *contains* a `fallthrough` token. 530 | fallthrough_statement: _ => prec.left('fallthrough'), 531 | 532 | break_statement: $ => seq('break', optional(alias($.identifier, $.label_name))), 533 | 534 | continue_statement: $ => seq('continue', optional(alias($.identifier, $.label_name))), 535 | 536 | goto_statement: $ => seq('goto', alias($.identifier, $.label_name)), 537 | 538 | return_statement: $ => seq('return', optional($.expression_list)), 539 | 540 | go_statement: $ => seq('go', $._expression), 541 | 542 | defer_statement: $ => seq('defer', $._expression), 543 | 544 | if_statement: $ => seq( 545 | 'if', 546 | optional(seq( 547 | field('initializer', $._simple_statement), 548 | ';', 549 | )), 550 | field('condition', $._expression), 551 | field('consequence', $.block), 552 | optional(seq( 553 | 'else', 554 | field('alternative', choice($.block, $.if_statement)), 555 | )), 556 | ), 557 | 558 | for_statement: $ => seq( 559 | 'for', 560 | optional(choice($._expression, $.for_clause, $.range_clause)), 561 | field('body', $.block), 562 | ), 563 | 564 | for_clause: $ => seq( 565 | field('initializer', optional($._simple_statement)), 566 | ';', 567 | field('condition', optional($._expression)), 568 | ';', 569 | field('update', optional($._simple_statement)), 570 | ), 571 | 572 | range_clause: $ => seq( 573 | optional(seq( 574 | field('left', $.expression_list), 575 | choice('=', ':='), 576 | )), 577 | 'range', 578 | field('right', $._expression), 579 | ), 580 | 581 | expression_switch_statement: $ => seq( 582 | 'switch', 583 | optional(seq( 584 | field('initializer', $._simple_statement), 585 | ';', 586 | )), 587 | field('value', optional($._expression)), 588 | '{', 589 | repeat(choice($.expression_case, $.default_case)), 590 | '}', 591 | ), 592 | 593 | expression_case: $ => seq( 594 | 'case', 595 | field('value', $.expression_list), 596 | ':', 597 | optional($._statement_list), 598 | ), 599 | 600 | default_case: $ => seq( 601 | 'default', 602 | ':', 603 | optional($._statement_list), 604 | ), 605 | 606 | type_switch_statement: $ => seq( 607 | 'switch', 608 | $._type_switch_header, 609 | '{', 610 | repeat(choice($.type_case, $.default_case)), 611 | '}', 612 | ), 613 | 614 | _type_switch_header: $ => seq( 615 | optional(seq( 616 | field('initializer', $._simple_statement), 617 | ';', 618 | )), 619 | optional(seq(field('alias', $.expression_list), ':=')), 620 | field('value', $._expression), 621 | '.', 622 | '(', 623 | 'type', 624 | ')', 625 | ), 626 | 627 | type_case: $ => seq( 628 | 'case', 629 | field('type', commaSep1($._type)), 630 | ':', 631 | optional($._statement_list), 632 | ), 633 | 634 | select_statement: $ => seq( 635 | 'select', 636 | '{', 637 | repeat(choice($.communication_case, $.default_case)), 638 | '}', 639 | ), 640 | 641 | communication_case: $ => seq( 642 | 'case', 643 | field('communication', choice($.send_statement, $.receive_statement)), 644 | ':', 645 | optional($._statement_list), 646 | ), 647 | 648 | _expression: $ => choice( 649 | $.unary_expression, 650 | $.binary_expression, 651 | $.selector_expression, 652 | $.index_expression, 653 | $.slice_expression, 654 | $.call_expression, 655 | $.type_assertion_expression, 656 | $.type_conversion_expression, 657 | $.type_instantiation_expression, 658 | $.identifier, 659 | alias(choice('new', 'make'), $.identifier), 660 | $.composite_literal, 661 | $.func_literal, 662 | $._string_literal, 663 | $.int_literal, 664 | $.float_literal, 665 | $.imaginary_literal, 666 | $.rune_literal, 667 | $.nil, 668 | $.true, 669 | $.false, 670 | $.iota, 671 | $.parenthesized_expression, 672 | ), 673 | 674 | parenthesized_expression: $ => seq( 675 | '(', 676 | $._expression, 677 | ')', 678 | ), 679 | 680 | call_expression: $ => prec(PREC.primary, choice( 681 | seq( 682 | field('function', alias(choice('new', 'make'), $.identifier)), 683 | field('arguments', alias($.special_argument_list, $.argument_list)), 684 | ), 685 | seq( 686 | field('function', $._expression), 687 | field('type_arguments', optional($.type_arguments)), 688 | field('arguments', $.argument_list), 689 | ), 690 | )), 691 | 692 | variadic_argument: $ => prec.right(seq( 693 | $._expression, 694 | '...', 695 | )), 696 | 697 | special_argument_list: $ => seq( 698 | '(', 699 | optional(seq( 700 | $._type, 701 | repeat(seq(',', $._expression)), 702 | optional(','), 703 | )), 704 | ')', 705 | ), 706 | 707 | argument_list: $ => seq( 708 | '(', 709 | optional(seq( 710 | choice($._expression, $.variadic_argument), 711 | repeat(seq(',', choice($._expression, $.variadic_argument))), 712 | optional(','), 713 | )), 714 | ')', 715 | ), 716 | 717 | selector_expression: $ => prec(PREC.primary, seq( 718 | field('operand', $._expression), 719 | '.', 720 | field('field', $._field_identifier), 721 | )), 722 | 723 | index_expression: $ => prec(PREC.primary, seq( 724 | field('operand', $._expression), 725 | '[', 726 | field('index', $._expression), 727 | ']', 728 | )), 729 | 730 | slice_expression: $ => prec(PREC.primary, seq( 731 | field('operand', $._expression), 732 | '[', 733 | choice( 734 | seq( 735 | field('start', optional($._expression)), 736 | ':', 737 | field('end', optional($._expression)), 738 | ), 739 | seq( 740 | field('start', optional($._expression)), 741 | ':', 742 | field('end', $._expression), 743 | ':', 744 | field('capacity', $._expression), 745 | ), 746 | ), 747 | ']', 748 | )), 749 | 750 | type_assertion_expression: $ => prec(PREC.primary, seq( 751 | field('operand', $._expression), 752 | '.', 753 | '(', 754 | field('type', $._type), 755 | ')', 756 | )), 757 | 758 | type_conversion_expression: $ => prec.dynamic(-1, seq( 759 | field('type', $._type), 760 | '(', 761 | field('operand', $._expression), 762 | optional(','), 763 | ')', 764 | )), 765 | 766 | type_instantiation_expression: $ => prec.dynamic(-1, seq( 767 | field('type', $._type), 768 | '[', 769 | commaSep1($._type), 770 | optional(','), 771 | ']', 772 | )), 773 | 774 | composite_literal: $ => prec(PREC.composite_literal, seq( 775 | field('type', choice( 776 | $.map_type, 777 | $.slice_type, 778 | $.array_type, 779 | $.implicit_length_array_type, 780 | $.struct_type, 781 | $._type_identifier, 782 | $.generic_type, 783 | $.qualified_type, 784 | )), 785 | field('body', $.literal_value), 786 | )), 787 | 788 | literal_value: $ => seq( 789 | '{', 790 | optional( 791 | seq( 792 | commaSep(choice($.literal_element, $.keyed_element)), 793 | optional(','))), 794 | '}', 795 | ), 796 | 797 | literal_element: $ => choice($._expression, $.literal_value), 798 | 799 | // In T{k: v}, the key k may be: 800 | // - any expression (when T is a map, slice or array), 801 | // - a field identifier (when T is a struct), or 802 | // - a literal_element (when T is an array). 803 | // The first two cases cannot be distinguished without type information. 804 | keyed_element: $ => seq( 805 | field('key', $.literal_element), 806 | ':', 807 | field('value', $.literal_element), 808 | ), 809 | 810 | func_literal: $ => seq( 811 | 'func', 812 | field('parameters', $.parameter_list), 813 | field('result', optional(choice($.parameter_list, $._simple_type))), 814 | field('body', $.block), 815 | ), 816 | 817 | unary_expression: $ => prec(PREC.unary, seq( 818 | field('operator', choice('+', '-', '!', '^', '*', '&', '<-')), 819 | field('operand', $._expression), 820 | )), 821 | 822 | binary_expression: $ => { 823 | const table = [ 824 | [PREC.multiplicative, choice(...multiplicativeOperators)], 825 | [PREC.additive, choice(...additiveOperators)], 826 | [PREC.comparative, choice(...comparativeOperators)], 827 | [PREC.and, '&&'], 828 | [PREC.or, '||'], 829 | ]; 830 | 831 | return choice(...table.map(([precedence, operator]) => 832 | // @ts-ignore 833 | prec.left(precedence, seq( 834 | field('left', $._expression), 835 | // @ts-ignore 836 | field('operator', operator), 837 | field('right', $._expression), 838 | )), 839 | )); 840 | }, 841 | 842 | qualified_type: $ => seq( 843 | field('package', $._package_identifier), 844 | '.', 845 | field('name', $._type_identifier), 846 | ), 847 | 848 | identifier: _ => /[_\p{XID_Start}][_\p{XID_Continue}]*/, 849 | 850 | _type_identifier: $ => alias($.identifier, $.type_identifier), 851 | _field_identifier: $ => alias($.identifier, $.field_identifier), 852 | _package_identifier: $ => alias($.identifier, $.package_identifier), 853 | 854 | _string_literal: $ => choice( 855 | $.raw_string_literal, 856 | $.interpreted_string_literal, 857 | ), 858 | 859 | raw_string_literal: $ => seq( 860 | '`', 861 | alias(token(prec(1, /[^`]*/)), $.raw_string_literal_content), 862 | '`', 863 | ), 864 | 865 | interpreted_string_literal: $ => seq( 866 | '"', 867 | repeat(choice( 868 | alias(token.immediate(prec(1, /[^"\n\\]+/)), $.interpreted_string_literal_content), 869 | $.escape_sequence, 870 | )), 871 | token.immediate('"'), 872 | ), 873 | 874 | escape_sequence: _ => token.immediate(seq( 875 | '\\', 876 | choice( 877 | /[^xuU]/, 878 | /\d{2,3}/, 879 | /x[0-9a-fA-F]{2,}/, 880 | /u[0-9a-fA-F]{4}/, 881 | /U[0-9a-fA-F]{8}/, 882 | ), 883 | )), 884 | 885 | int_literal: _ => token(intLiteral), 886 | 887 | float_literal: _ => token(floatLiteral), 888 | 889 | imaginary_literal: _ => token(imaginaryLiteral), 890 | 891 | rune_literal: _ => token(seq( 892 | '\'', 893 | choice( 894 | /[^'\\]/, 895 | seq( 896 | '\\', 897 | choice( 898 | seq('x', hexDigit, hexDigit), 899 | seq(octalDigit, octalDigit, octalDigit), 900 | seq('u', hexDigit, hexDigit, hexDigit, hexDigit), 901 | seq('U', hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit), 902 | seq(choice('a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"')), 903 | ), 904 | ), 905 | ), 906 | '\'', 907 | )), 908 | 909 | nil: _ => 'nil', 910 | true: _ => 'true', 911 | false: _ => 'false', 912 | iota: _ => 'iota', 913 | 914 | // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890 915 | comment: _ => token(choice( 916 | seq('//', /.*/), 917 | seq( 918 | '/*', 919 | /[^*]*\*+([^/*][^*]*\*+)*/, 920 | '/', 921 | ), 922 | )), 923 | }, 924 | }); 925 | 926 | /** 927 | * Creates a rule to match one or more occurrences of `rule` separated by `sep` 928 | * 929 | * @param {RuleOrLiteral} rule 930 | * 931 | * @param {RuleOrLiteral} separator 932 | * 933 | * @returns {SeqRule} 934 | */ 935 | function sep1(rule, separator) { 936 | return seq(rule, repeat(seq(separator, rule))); 937 | } 938 | 939 | /** 940 | * Creates a rule to match one or more of the rules separated by a comma 941 | * 942 | * @param {Rule} rule 943 | * 944 | * @returns {SeqRule} 945 | */ 946 | function commaSep1(rule) { 947 | return seq(rule, repeat(seq(',', rule))); 948 | } 949 | 950 | /** 951 | * Creates a rule to optionally match one or more of the rules separated by a comma 952 | * 953 | * @param {Rule} rule 954 | * 955 | * @returns {ChoiceRule} 956 | */ 957 | function commaSep(rule) { 958 | return optional(commaSep1(rule)); 959 | } 960 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-go", 3 | "version": "0.23.4", 4 | "description": "Go grammar for tree-sitter", 5 | "repository": "https://github.com/tree-sitter/tree-sitter-go", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Max Brunsfeld", 9 | "email": "maxbrunsfeld@gmail.com" 10 | }, 11 | "maintainers": [ 12 | { 13 | "name": "Amaan Qureshi", 14 | "email": "amaanq12@gmail.com" 15 | } 16 | ], 17 | "main": "bindings/node", 18 | "types": "bindings/node", 19 | "keywords": [ 20 | "incremental", 21 | "parsing", 22 | "tree-sitter", 23 | "go" 24 | ], 25 | "files": [ 26 | "grammar.js", 27 | "tree-sitter.json", 28 | "binding.gyp", 29 | "prebuilds/**", 30 | "bindings/node/*", 31 | "queries/*", 32 | "src/**", 33 | "*.wasm" 34 | ], 35 | "dependencies": { 36 | "node-addon-api": "^8.2.1", 37 | "node-gyp-build": "^4.8.2" 38 | }, 39 | "devDependencies": { 40 | "eslint": "^9.12.0", 41 | "eslint-config-treesitter": "^1.0.2", 42 | "tree-sitter-cli": "^0.24.3", 43 | "prebuildify": "^6.0.1" 44 | }, 45 | "peerDependencies": { 46 | "tree-sitter": "^0.21.1" 47 | }, 48 | "peerDependenciesMeta": { 49 | "tree-sitter": { 50 | "optional": true 51 | } 52 | }, 53 | "scripts": { 54 | "install": "node-gyp-build", 55 | "lint": "eslint grammar.js", 56 | "prestart": "tree-sitter build --wasm", 57 | "start": "tree-sitter playground", 58 | "test": "node --test bindings/node/*_test.js" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-go" 7 | description = "Go grammar for tree-sitter" 8 | version = "0.23.4" 9 | keywords = ["incremental", "parsing", "tree-sitter", "go"] 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 = [ 18 | { name = "Max Brunsfeld", email = "maxbrunsfeld@gmail.com" }, 19 | { name = "Amaan Qureshi", email = "amaanq12@gmail.com" }, 20 | ] 21 | requires-python = ">=3.9" 22 | license.text = "MIT" 23 | readme = "README.md" 24 | 25 | [project.urls] 26 | Homepage = "https://github.com/tree-sitter/tree-sitter-go" 27 | 28 | [project.optional-dependencies] 29 | core = ["tree-sitter~=0.22"] 30 | 31 | [tool.cibuildwheel] 32 | build = "cp39-*" 33 | build-frontend = "build" 34 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | ; Function calls 2 | 3 | (call_expression 4 | function: (identifier) @function) 5 | 6 | (call_expression 7 | function: (identifier) @function.builtin 8 | (#match? @function.builtin "^(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)$")) 9 | 10 | (call_expression 11 | function: (selector_expression 12 | field: (field_identifier) @function.method)) 13 | 14 | ; Function definitions 15 | 16 | (function_declaration 17 | name: (identifier) @function) 18 | 19 | (method_declaration 20 | name: (field_identifier) @function.method) 21 | 22 | ; Identifiers 23 | 24 | (type_identifier) @type 25 | (field_identifier) @property 26 | (identifier) @variable 27 | 28 | ; Operators 29 | 30 | [ 31 | "--" 32 | "-" 33 | "-=" 34 | ":=" 35 | "!" 36 | "!=" 37 | "..." 38 | "*" 39 | "*" 40 | "*=" 41 | "/" 42 | "/=" 43 | "&" 44 | "&&" 45 | "&=" 46 | "%" 47 | "%=" 48 | "^" 49 | "^=" 50 | "+" 51 | "++" 52 | "+=" 53 | "<-" 54 | "<" 55 | "<<" 56 | "<<=" 57 | "<=" 58 | "=" 59 | "==" 60 | ">" 61 | ">=" 62 | ">>" 63 | ">>=" 64 | "|" 65 | "|=" 66 | "||" 67 | "~" 68 | ] @operator 69 | 70 | ; Keywords 71 | 72 | [ 73 | "break" 74 | "case" 75 | "chan" 76 | "const" 77 | "continue" 78 | "default" 79 | "defer" 80 | "else" 81 | "fallthrough" 82 | "for" 83 | "func" 84 | "go" 85 | "goto" 86 | "if" 87 | "import" 88 | "interface" 89 | "map" 90 | "package" 91 | "range" 92 | "return" 93 | "select" 94 | "struct" 95 | "switch" 96 | "type" 97 | "var" 98 | ] @keyword 99 | 100 | ; Literals 101 | 102 | [ 103 | (interpreted_string_literal) 104 | (raw_string_literal) 105 | (rune_literal) 106 | ] @string 107 | 108 | (escape_sequence) @escape 109 | 110 | [ 111 | (int_literal) 112 | (float_literal) 113 | (imaginary_literal) 114 | ] @number 115 | 116 | [ 117 | (true) 118 | (false) 119 | (nil) 120 | (iota) 121 | ] @constant.builtin 122 | 123 | (comment) @comment 124 | -------------------------------------------------------------------------------- /queries/tags.scm: -------------------------------------------------------------------------------- 1 | ( 2 | (comment)* @doc 3 | . 4 | (function_declaration 5 | name: (identifier) @name) @definition.function 6 | (#strip! @doc "^//\\s*") 7 | (#set-adjacent! @doc @definition.function) 8 | ) 9 | 10 | ( 11 | (comment)* @doc 12 | . 13 | (method_declaration 14 | name: (field_identifier) @name) @definition.method 15 | (#strip! @doc "^//\\s*") 16 | (#set-adjacent! @doc @definition.method) 17 | ) 18 | 19 | (call_expression 20 | function: [ 21 | (identifier) @name 22 | (parenthesized_expression (identifier) @name) 23 | (selector_expression field: (field_identifier) @name) 24 | (parenthesized_expression (selector_expression field: (field_identifier) @name)) 25 | ]) @reference.call 26 | 27 | (type_spec 28 | name: (type_identifier) @name) @definition.type 29 | 30 | (type_identifier) @name @reference.type 31 | 32 | (package_clause "package" (package_identifier) @name) 33 | 34 | (type_declaration (type_spec name: (type_identifier) @name type: (interface_type))) 35 | 36 | (type_declaration (type_spec name: (type_identifier) @name type: (struct_type))) 37 | 38 | (import_declaration (import_spec) @name) 39 | 40 | (var_declaration (var_spec name: (identifier) @name)) 41 | 42 | (const_declaration (const_spec name: (identifier) @name)) 43 | -------------------------------------------------------------------------------- /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_go", "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_go": ["*.pyi", "py.typed"], 30 | "tree_sitter_go.queries": ["*.scm"], 31 | }, 32 | ext_package="tree_sitter_go", 33 | ext_modules=[ 34 | Extension( 35 | name="_binding", 36 | sources=[ 37 | "bindings/python/tree_sitter_go/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/declarations.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Single const declarations without types 3 | ================================================================================ 4 | 5 | package main 6 | 7 | const zero = 0 8 | const one, two = 1, 2 9 | const three, four, five = 3, 4, 5 10 | 11 | -------------------------------------------------------------------------------- 12 | 13 | (source_file 14 | (package_clause 15 | (package_identifier)) 16 | (const_declaration 17 | (const_spec 18 | (identifier) 19 | (expression_list 20 | (int_literal)))) 21 | (const_declaration 22 | (const_spec 23 | (identifier) 24 | (identifier) 25 | (expression_list 26 | (int_literal) 27 | (int_literal)))) 28 | (const_declaration 29 | (const_spec 30 | (identifier) 31 | (identifier) 32 | (identifier) 33 | (expression_list 34 | (int_literal) 35 | (int_literal) 36 | (int_literal))))) 37 | 38 | ================================================================================ 39 | Single const declarations with types 40 | ================================================================================ 41 | 42 | package main 43 | 44 | const zero int = 0 45 | const one, two uint64 = 1, 2 46 | 47 | -------------------------------------------------------------------------------- 48 | 49 | (source_file 50 | (package_clause 51 | (package_identifier)) 52 | (const_declaration 53 | (const_spec 54 | (identifier) 55 | (type_identifier) 56 | (expression_list 57 | (int_literal)))) 58 | (const_declaration 59 | (const_spec 60 | (identifier) 61 | (identifier) 62 | (type_identifier) 63 | (expression_list 64 | (int_literal) 65 | (int_literal))))) 66 | 67 | ================================================================================ 68 | Grouped const declarations 69 | ================================================================================ 70 | 71 | package main 72 | 73 | const ( 74 | zero = 0 75 | one = 1 76 | ) 77 | 78 | -------------------------------------------------------------------------------- 79 | 80 | (source_file 81 | (package_clause 82 | (package_identifier)) 83 | (const_declaration 84 | (const_spec 85 | (identifier) 86 | (expression_list 87 | (int_literal))) 88 | (const_spec 89 | (identifier) 90 | (expression_list 91 | (int_literal))))) 92 | 93 | ================================================================================ 94 | Const declarations with implicit values 95 | ================================================================================ 96 | 97 | package main 98 | 99 | const ( 100 | zero = iota 101 | one 102 | two 103 | ) 104 | 105 | -------------------------------------------------------------------------------- 106 | 107 | (source_file 108 | (package_clause 109 | (package_identifier)) 110 | (const_declaration 111 | (const_spec 112 | (identifier) 113 | (expression_list 114 | (iota))) 115 | (const_spec 116 | (identifier)) 117 | (const_spec 118 | (identifier)))) 119 | 120 | ================================================================================ 121 | Var declarations without types 122 | ================================================================================ 123 | 124 | package main 125 | 126 | var zero = 0 127 | var one, two = 1, 2 128 | var three, four, five = 3, 4, 5 129 | 130 | -------------------------------------------------------------------------------- 131 | 132 | (source_file 133 | (package_clause 134 | (package_identifier)) 135 | (var_declaration 136 | (var_spec 137 | (identifier) 138 | (expression_list 139 | (int_literal)))) 140 | (var_declaration 141 | (var_spec 142 | (identifier) 143 | (identifier) 144 | (expression_list 145 | (int_literal) 146 | (int_literal)))) 147 | (var_declaration 148 | (var_spec 149 | (identifier) 150 | (identifier) 151 | (identifier) 152 | (expression_list 153 | (int_literal) 154 | (int_literal) 155 | (int_literal))))) 156 | 157 | ================================================================================ 158 | Var declarations with types 159 | ================================================================================ 160 | 161 | package main 162 | 163 | var zero int = 0 164 | var one, two uint64 = 1, 2 165 | 166 | -------------------------------------------------------------------------------- 167 | 168 | (source_file 169 | (package_clause 170 | (package_identifier)) 171 | (var_declaration 172 | (var_spec 173 | (identifier) 174 | (type_identifier) 175 | (expression_list 176 | (int_literal)))) 177 | (var_declaration 178 | (var_spec 179 | (identifier) 180 | (identifier) 181 | (type_identifier) 182 | (expression_list 183 | (int_literal) 184 | (int_literal))))) 185 | 186 | ================================================================================ 187 | Var declarations with no expressions 188 | ================================================================================ 189 | 190 | package main 191 | 192 | var zero int 193 | var one, two uint64 194 | 195 | -------------------------------------------------------------------------------- 196 | 197 | (source_file 198 | (package_clause 199 | (package_identifier)) 200 | (var_declaration 201 | (var_spec 202 | (identifier) 203 | (type_identifier))) 204 | (var_declaration 205 | (var_spec 206 | (identifier) 207 | (identifier) 208 | (type_identifier)))) 209 | 210 | ================================================================================ 211 | Grouped var declarations 212 | ================================================================================ 213 | 214 | package main 215 | 216 | var ( 217 | zero = 0 218 | one = 1 219 | ) 220 | 221 | -------------------------------------------------------------------------------- 222 | 223 | (source_file 224 | (package_clause 225 | (package_identifier)) 226 | (var_declaration 227 | (var_spec_list 228 | (var_spec 229 | (identifier) 230 | (expression_list 231 | (int_literal))) 232 | (var_spec 233 | (identifier) 234 | (expression_list 235 | (int_literal)))))) 236 | 237 | ================================================================================ 238 | Function declarations 239 | ================================================================================ 240 | 241 | package main 242 | 243 | func f1() {} 244 | func f2(a File, b, c, d Thing) int {} 245 | func f2() (File, Thing) {} 246 | func f2() (result int, err error) {} 247 | func f(x ... int, y ... int) 248 | func g1[T, U any, V interface{}, W Foo[Bar[T]]](a Foo[T]) {} 249 | func g1[T, U any, V interface{}, W Foo[Bar[T]]](a Foo[T]) {} 250 | func g2(a foo.bar[int]) {} 251 | func f[A int|string, B ~int, C ~int|~string]() 252 | func f2(a File, b, c, d Thing) int {} 253 | func f3([]string, int, map[int]int, error) {} 254 | func f4() ([]string, int, map[int]int, error) {} 255 | 256 | -------------------------------------------------------------------------------- 257 | 258 | (source_file 259 | (package_clause 260 | (package_identifier)) 261 | (function_declaration 262 | (identifier) 263 | (parameter_list) 264 | (block)) 265 | (function_declaration 266 | (identifier) 267 | (parameter_list 268 | (parameter_declaration 269 | (identifier) 270 | (type_identifier)) 271 | (parameter_declaration 272 | (identifier) 273 | (identifier) 274 | (identifier) 275 | (type_identifier))) 276 | (type_identifier) 277 | (block)) 278 | (function_declaration 279 | (identifier) 280 | (parameter_list) 281 | (parameter_list 282 | (parameter_declaration 283 | (type_identifier)) 284 | (parameter_declaration 285 | (type_identifier))) 286 | (block)) 287 | (function_declaration 288 | (identifier) 289 | (parameter_list) 290 | (parameter_list 291 | (parameter_declaration 292 | (identifier) 293 | (type_identifier)) 294 | (parameter_declaration 295 | (identifier) 296 | (type_identifier))) 297 | (block)) 298 | (function_declaration 299 | (identifier) 300 | (parameter_list 301 | (variadic_parameter_declaration 302 | (identifier) 303 | (type_identifier)) 304 | (variadic_parameter_declaration 305 | (identifier) 306 | (type_identifier)))) 307 | (function_declaration 308 | (identifier) 309 | (type_parameter_list 310 | (type_parameter_declaration 311 | (identifier) 312 | (identifier) 313 | (type_constraint 314 | (type_identifier))) 315 | (type_parameter_declaration 316 | (identifier) 317 | (type_constraint 318 | (interface_type))) 319 | (type_parameter_declaration 320 | (identifier) 321 | (type_constraint 322 | (generic_type 323 | (type_identifier) 324 | (type_arguments 325 | (type_elem 326 | (generic_type 327 | (type_identifier) 328 | (type_arguments 329 | (type_elem 330 | (type_identifier)))))))))) 331 | (parameter_list 332 | (parameter_declaration 333 | (identifier) 334 | (generic_type 335 | (type_identifier) 336 | (type_arguments 337 | (type_elem 338 | (type_identifier)))))) 339 | (block)) 340 | (function_declaration 341 | (identifier) 342 | (type_parameter_list 343 | (type_parameter_declaration 344 | (identifier) 345 | (identifier) 346 | (type_constraint 347 | (type_identifier))) 348 | (type_parameter_declaration 349 | (identifier) 350 | (type_constraint 351 | (interface_type))) 352 | (type_parameter_declaration 353 | (identifier) 354 | (type_constraint 355 | (generic_type 356 | (type_identifier) 357 | (type_arguments 358 | (type_elem 359 | (generic_type 360 | (type_identifier) 361 | (type_arguments 362 | (type_elem 363 | (type_identifier)))))))))) 364 | (parameter_list 365 | (parameter_declaration 366 | (identifier) 367 | (generic_type 368 | (type_identifier) 369 | (type_arguments 370 | (type_elem 371 | (type_identifier)))))) 372 | (block)) 373 | (function_declaration 374 | (identifier) 375 | (parameter_list 376 | (parameter_declaration 377 | (identifier) 378 | (generic_type 379 | (qualified_type 380 | (package_identifier) 381 | (type_identifier)) 382 | (type_arguments 383 | (type_elem 384 | (type_identifier)))))) 385 | (block)) 386 | (function_declaration 387 | (identifier) 388 | (type_parameter_list 389 | (type_parameter_declaration 390 | (identifier) 391 | (type_constraint 392 | (type_identifier) 393 | (type_identifier))) 394 | (type_parameter_declaration 395 | (identifier) 396 | (type_constraint 397 | (negated_type 398 | (type_identifier)))) 399 | (type_parameter_declaration 400 | (identifier) 401 | (type_constraint 402 | (negated_type 403 | (type_identifier)) 404 | (negated_type 405 | (type_identifier))))) 406 | (parameter_list)) 407 | (function_declaration 408 | (identifier) 409 | (parameter_list 410 | (parameter_declaration 411 | (identifier) 412 | (type_identifier)) 413 | (parameter_declaration 414 | (identifier) 415 | (identifier) 416 | (identifier) 417 | (type_identifier))) 418 | (type_identifier) 419 | (block)) 420 | (function_declaration 421 | (identifier) 422 | (parameter_list 423 | (parameter_declaration 424 | (slice_type 425 | (type_identifier))) 426 | (parameter_declaration 427 | (type_identifier)) 428 | (parameter_declaration 429 | (map_type 430 | (type_identifier) 431 | (type_identifier))) 432 | (parameter_declaration 433 | (type_identifier))) 434 | (block)) 435 | (function_declaration 436 | (identifier) 437 | (parameter_list) 438 | (parameter_list 439 | (parameter_declaration 440 | (slice_type 441 | (type_identifier))) 442 | (parameter_declaration 443 | (type_identifier)) 444 | (parameter_declaration 445 | (map_type 446 | (type_identifier) 447 | (type_identifier))) 448 | (parameter_declaration 449 | (type_identifier))) 450 | (block))) 451 | 452 | ================================================================================ 453 | Single-line function declarations 454 | ================================================================================ 455 | 456 | package main 457 | 458 | func f1() { a() } 459 | func f2() { a(); b() } 460 | func f3() { a(); b(); } 461 | 462 | -------------------------------------------------------------------------------- 463 | 464 | (source_file 465 | (package_clause 466 | (package_identifier)) 467 | (function_declaration 468 | (identifier) 469 | (parameter_list) 470 | (block 471 | (expression_statement 472 | (call_expression 473 | (identifier) 474 | (argument_list))))) 475 | (function_declaration 476 | (identifier) 477 | (parameter_list) 478 | (block 479 | (expression_statement 480 | (call_expression 481 | (identifier) 482 | (argument_list))) 483 | (expression_statement 484 | (call_expression 485 | (identifier) 486 | (argument_list))))) 487 | (function_declaration 488 | (identifier) 489 | (parameter_list) 490 | (block 491 | (expression_statement 492 | (call_expression 493 | (identifier) 494 | (argument_list))) 495 | (expression_statement 496 | (call_expression 497 | (identifier) 498 | (argument_list)))))) 499 | 500 | ================================================================================ 501 | Variadic function declarations 502 | ================================================================================ 503 | 504 | package main 505 | 506 | func f1(a ...*int) {} 507 | func f2(a int, b ...int) {} 508 | func f3(...bool) {} 509 | 510 | -------------------------------------------------------------------------------- 511 | 512 | (source_file 513 | (package_clause 514 | (package_identifier)) 515 | (function_declaration 516 | (identifier) 517 | (parameter_list 518 | (variadic_parameter_declaration 519 | (identifier) 520 | (pointer_type 521 | (type_identifier)))) 522 | (block)) 523 | (function_declaration 524 | (identifier) 525 | (parameter_list 526 | (parameter_declaration 527 | (identifier) 528 | (type_identifier)) 529 | (variadic_parameter_declaration 530 | (identifier) 531 | (type_identifier))) 532 | (block)) 533 | (function_declaration 534 | (identifier) 535 | (parameter_list 536 | (variadic_parameter_declaration 537 | (type_identifier))) 538 | (block))) 539 | 540 | ================================================================================ 541 | Method declarations 542 | ================================================================================ 543 | 544 | package main 545 | 546 | func (self Person) Equals(other Person) bool {} 547 | func (v *Value) ObjxMap(optionalDefault ...(Map)) Map {} 548 | func (p *T1) M1() 549 | 550 | -------------------------------------------------------------------------------- 551 | 552 | (source_file 553 | (package_clause 554 | (package_identifier)) 555 | (method_declaration 556 | (parameter_list 557 | (parameter_declaration 558 | (identifier) 559 | (type_identifier))) 560 | (field_identifier) 561 | (parameter_list 562 | (parameter_declaration 563 | (identifier) 564 | (type_identifier))) 565 | (type_identifier) 566 | (block)) 567 | (method_declaration 568 | (parameter_list 569 | (parameter_declaration 570 | (identifier) 571 | (pointer_type 572 | (type_identifier)))) 573 | (field_identifier) 574 | (parameter_list 575 | (variadic_parameter_declaration 576 | (identifier) 577 | (parenthesized_type 578 | (type_identifier)))) 579 | (type_identifier) 580 | (block)) 581 | (method_declaration 582 | (parameter_list 583 | (parameter_declaration 584 | (identifier) 585 | (pointer_type 586 | (type_identifier)))) 587 | (field_identifier) 588 | (parameter_list))) 589 | 590 | ================================================================================ 591 | Type declarations 592 | ================================================================================ 593 | 594 | package main 595 | 596 | type a b 597 | type ( 598 | a b 599 | c d 600 | ) 601 | 602 | -------------------------------------------------------------------------------- 603 | 604 | (source_file 605 | (package_clause 606 | (package_identifier)) 607 | (type_declaration 608 | (type_spec 609 | (type_identifier) 610 | (type_identifier))) 611 | (type_declaration 612 | (type_spec 613 | (type_identifier) 614 | (type_identifier)) 615 | (type_spec 616 | (type_identifier) 617 | (type_identifier)))) 618 | -------------------------------------------------------------------------------- /test/corpus/expressions.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Call expressions 3 | ================================================================================ 4 | 5 | package main 6 | 7 | func main() { 8 | a(b, c...) 9 | 10 | a( 11 | b, 12 | c, 13 | ) 14 | 15 | a( 16 | b, 17 | c..., 18 | ) 19 | } 20 | 21 | -------------------------------------------------------------------------------- 22 | 23 | (source_file 24 | (package_clause 25 | (package_identifier)) 26 | (function_declaration 27 | (identifier) 28 | (parameter_list) 29 | (block 30 | (expression_statement 31 | (call_expression 32 | (identifier) 33 | (argument_list 34 | (identifier) 35 | (variadic_argument 36 | (identifier))))) 37 | (expression_statement 38 | (call_expression 39 | (identifier) 40 | (argument_list 41 | (identifier) 42 | (identifier)))) 43 | (expression_statement 44 | (call_expression 45 | (identifier) 46 | (argument_list 47 | (identifier) 48 | (variadic_argument 49 | (identifier)))))))) 50 | 51 | ================================================================================ 52 | Nested call expressions 53 | ================================================================================ 54 | 55 | package main 56 | 57 | func main() { 58 | a(b(c(d))) 59 | } 60 | 61 | -------------------------------------------------------------------------------- 62 | 63 | (source_file 64 | (package_clause 65 | (package_identifier)) 66 | (function_declaration 67 | (identifier) 68 | (parameter_list) 69 | (block 70 | (expression_statement 71 | (call_expression 72 | (identifier) 73 | (argument_list 74 | (call_expression 75 | (identifier) 76 | (argument_list 77 | (call_expression 78 | (identifier) 79 | (argument_list 80 | (identifier))))))))))) 81 | 82 | ================================================================================ 83 | Generic call expressions 84 | ================================================================================ 85 | 86 | package main 87 | 88 | func main() { 89 | a[b](c) 90 | a[b, c](d) 91 | a[b[c], d](e[f]) 92 | } 93 | 94 | -------------------------------------------------------------------------------- 95 | 96 | (source_file 97 | (package_clause 98 | (package_identifier)) 99 | (function_declaration 100 | (identifier) 101 | (parameter_list) 102 | (block 103 | (expression_statement 104 | (type_conversion_expression 105 | (generic_type 106 | (type_identifier) 107 | (type_arguments 108 | (type_elem 109 | (type_identifier)))) 110 | (identifier))) 111 | (expression_statement 112 | (type_conversion_expression 113 | (generic_type 114 | (type_identifier) 115 | (type_arguments 116 | (type_elem 117 | (type_identifier)) 118 | (type_elem 119 | (type_identifier)))) 120 | (identifier))) 121 | (expression_statement 122 | (type_conversion_expression 123 | (generic_type 124 | (type_identifier) 125 | (type_arguments 126 | (type_elem 127 | (generic_type 128 | (type_identifier) 129 | (type_arguments 130 | (type_elem 131 | (type_identifier))))) 132 | (type_elem 133 | (type_identifier)))) 134 | (index_expression 135 | (identifier) 136 | (identifier))))))) 137 | 138 | ================================================================================ 139 | Calls to 'make' and 'new' 140 | ================================================================================ 141 | 142 | package main 143 | 144 | func main() { 145 | make(chan<- int) 146 | 147 | // `new` and `make` can also be used as variable names 148 | make(chan<- int, (new - old), make.stuff) 149 | 150 | make(chan<- int, 5, 10) 151 | new(map[string]string) 152 | } 153 | 154 | func fake_new(new func() int) int { 155 | return new() 156 | } 157 | 158 | -------------------------------------------------------------------------------- 159 | 160 | (source_file 161 | (package_clause 162 | (package_identifier)) 163 | (function_declaration 164 | (identifier) 165 | (parameter_list) 166 | (block 167 | (expression_statement 168 | (call_expression 169 | (identifier) 170 | (argument_list 171 | (channel_type 172 | (type_identifier))))) 173 | (comment) 174 | (expression_statement 175 | (call_expression 176 | (identifier) 177 | (argument_list 178 | (channel_type 179 | (type_identifier)) 180 | (parenthesized_expression 181 | (binary_expression 182 | (identifier) 183 | (identifier))) 184 | (selector_expression 185 | (identifier) 186 | (field_identifier))))) 187 | (expression_statement 188 | (call_expression 189 | (identifier) 190 | (argument_list 191 | (channel_type 192 | (type_identifier)) 193 | (int_literal) 194 | (int_literal)))) 195 | (expression_statement 196 | (call_expression 197 | (identifier) 198 | (argument_list 199 | (map_type 200 | (type_identifier) 201 | (type_identifier))))))) 202 | (function_declaration 203 | (identifier) 204 | (parameter_list 205 | (parameter_declaration 206 | (identifier) 207 | (function_type 208 | (parameter_list) 209 | (type_identifier)))) 210 | (type_identifier) 211 | (block 212 | (return_statement 213 | (expression_list 214 | (call_expression 215 | (identifier) 216 | (argument_list))))))) 217 | 218 | ================================================================================ 219 | Selector expressions 220 | ================================================================================ 221 | 222 | package main 223 | 224 | func main() { 225 | a.b.c() 226 | } 227 | 228 | -------------------------------------------------------------------------------- 229 | 230 | (source_file 231 | (package_clause 232 | (package_identifier)) 233 | (function_declaration 234 | (identifier) 235 | (parameter_list) 236 | (block 237 | (expression_statement 238 | (call_expression 239 | (selector_expression 240 | (selector_expression 241 | (identifier) 242 | (field_identifier)) 243 | (field_identifier)) 244 | (argument_list)))))) 245 | 246 | ================================================================================ 247 | Indexing expressions 248 | ================================================================================ 249 | 250 | package main 251 | 252 | func main() { 253 | _ = a[1] 254 | _ = b[:] 255 | _ = c[1:] 256 | _ = d[1:2] 257 | _ = e[:2:3] 258 | _ = f[1:2:3] 259 | } 260 | 261 | -------------------------------------------------------------------------------- 262 | 263 | (source_file 264 | (package_clause 265 | (package_identifier)) 266 | (function_declaration 267 | (identifier) 268 | (parameter_list) 269 | (block 270 | (assignment_statement 271 | (expression_list 272 | (identifier)) 273 | (expression_list 274 | (index_expression 275 | (identifier) 276 | (int_literal)))) 277 | (assignment_statement 278 | (expression_list 279 | (identifier)) 280 | (expression_list 281 | (slice_expression 282 | (identifier)))) 283 | (assignment_statement 284 | (expression_list 285 | (identifier)) 286 | (expression_list 287 | (slice_expression 288 | (identifier) 289 | (int_literal)))) 290 | (assignment_statement 291 | (expression_list 292 | (identifier)) 293 | (expression_list 294 | (slice_expression 295 | (identifier) 296 | (int_literal) 297 | (int_literal)))) 298 | (assignment_statement 299 | (expression_list 300 | (identifier)) 301 | (expression_list 302 | (slice_expression 303 | (identifier) 304 | (int_literal) 305 | (int_literal)))) 306 | (assignment_statement 307 | (expression_list 308 | (identifier)) 309 | (expression_list 310 | (slice_expression 311 | (identifier) 312 | (int_literal) 313 | (int_literal) 314 | (int_literal))))))) 315 | 316 | ================================================================================ 317 | Type assertion expressions 318 | ================================================================================ 319 | 320 | package main 321 | 322 | func main() { 323 | _ = a.(p.Person) 324 | } 325 | 326 | -------------------------------------------------------------------------------- 327 | 328 | (source_file 329 | (package_clause 330 | (package_identifier)) 331 | (function_declaration 332 | (identifier) 333 | (parameter_list) 334 | (block 335 | (assignment_statement 336 | (expression_list 337 | (identifier)) 338 | (expression_list 339 | (type_assertion_expression 340 | (identifier) 341 | (qualified_type 342 | (package_identifier) 343 | (type_identifier)))))))) 344 | 345 | ================================================================================ 346 | Type conversion expressions 347 | ================================================================================ 348 | 349 | package main 350 | 351 | func main() { 352 | _ = []a.b(c.d) 353 | _ = ([]a.b)(c.d) 354 | _ = <-chan int(c) // conversion to channel type 355 | <-(chan int(c)) // receive statement 356 | // These type conversions cannot be distinguished from call expressions 357 | T(x) 358 | (*Point)(p) 359 | e.f(g) 360 | (e.f)(g) 361 | } 362 | 363 | -------------------------------------------------------------------------------- 364 | 365 | (source_file 366 | (package_clause 367 | (package_identifier)) 368 | (function_declaration 369 | (identifier) 370 | (parameter_list) 371 | (block 372 | (assignment_statement 373 | (expression_list 374 | (identifier)) 375 | (expression_list 376 | (type_conversion_expression 377 | (slice_type 378 | (qualified_type 379 | (package_identifier) 380 | (type_identifier))) 381 | (selector_expression 382 | (identifier) 383 | (field_identifier))))) 384 | (assignment_statement 385 | (expression_list 386 | (identifier)) 387 | (expression_list 388 | (type_conversion_expression 389 | (parenthesized_type 390 | (slice_type 391 | (qualified_type 392 | (package_identifier) 393 | (type_identifier)))) 394 | (selector_expression 395 | (identifier) 396 | (field_identifier))))) 397 | (assignment_statement 398 | (expression_list 399 | (identifier)) 400 | (expression_list 401 | (type_conversion_expression 402 | (channel_type 403 | (type_identifier)) 404 | (identifier)))) 405 | (comment) 406 | (expression_statement 407 | (unary_expression 408 | (parenthesized_expression 409 | (type_conversion_expression 410 | (channel_type 411 | (type_identifier)) 412 | (identifier))))) 413 | (comment) 414 | (comment) 415 | (expression_statement 416 | (call_expression 417 | (identifier) 418 | (argument_list 419 | (identifier)))) 420 | (expression_statement 421 | (call_expression 422 | (parenthesized_expression 423 | (unary_expression 424 | (identifier))) 425 | (argument_list 426 | (identifier)))) 427 | (expression_statement 428 | (call_expression 429 | (selector_expression 430 | (identifier) 431 | (field_identifier)) 432 | (argument_list 433 | (identifier)))) 434 | (expression_statement 435 | (call_expression 436 | (parenthesized_expression 437 | (selector_expression 438 | (identifier) 439 | (field_identifier))) 440 | (argument_list 441 | (identifier))))))) 442 | 443 | ================================================================================ 444 | Unary expressions 445 | ================================================================================ 446 | 447 | package main 448 | 449 | func main() { 450 | _ = !<-a 451 | _ = *foo() 452 | } 453 | 454 | -------------------------------------------------------------------------------- 455 | 456 | (source_file 457 | (package_clause 458 | (package_identifier)) 459 | (function_declaration 460 | (identifier) 461 | (parameter_list) 462 | (block 463 | (assignment_statement 464 | (expression_list 465 | (identifier)) 466 | (expression_list 467 | (unary_expression 468 | (unary_expression 469 | (identifier))))) 470 | (assignment_statement 471 | (expression_list 472 | (identifier)) 473 | (expression_list 474 | (unary_expression 475 | (call_expression 476 | (identifier) 477 | (argument_list)))))))) 478 | -------------------------------------------------------------------------------- /test/corpus/literals.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Int literals 3 | ================================================================================ 4 | 5 | package main 6 | 7 | const ( 8 | i1 = 42 9 | i2 = 4_2 10 | i3 = 0600 11 | i4 = 0_600 12 | i5 = 0o600 13 | i6 = 0O600 14 | i7 = 0xBadFace 15 | i8 = 0xBad_Face 16 | i9 = 0x_67_7a_2f_cc_40_c6 17 | i10 = 170141183460469231731687303715884105727 18 | i11 = 170_141183_460469_231731_687303_715884_105727 19 | ) 20 | 21 | -------------------------------------------------------------------------------- 22 | 23 | (source_file 24 | (package_clause 25 | (package_identifier)) 26 | (const_declaration 27 | (const_spec 28 | (identifier) 29 | (expression_list 30 | (int_literal))) 31 | (const_spec 32 | (identifier) 33 | (expression_list 34 | (int_literal))) 35 | (const_spec 36 | (identifier) 37 | (expression_list 38 | (int_literal))) 39 | (const_spec 40 | (identifier) 41 | (expression_list 42 | (int_literal))) 43 | (const_spec 44 | (identifier) 45 | (expression_list 46 | (int_literal))) 47 | (const_spec 48 | (identifier) 49 | (expression_list 50 | (int_literal))) 51 | (const_spec 52 | (identifier) 53 | (expression_list 54 | (int_literal))) 55 | (const_spec 56 | (identifier) 57 | (expression_list 58 | (int_literal))) 59 | (const_spec 60 | (identifier) 61 | (expression_list 62 | (int_literal))) 63 | (const_spec 64 | (identifier) 65 | (expression_list 66 | (int_literal))) 67 | (const_spec 68 | (identifier) 69 | (expression_list 70 | (int_literal))))) 71 | 72 | ================================================================================ 73 | Float literals 74 | ================================================================================ 75 | 76 | package main 77 | 78 | const ( 79 | f1 = 0. 80 | f2 = 72.40 81 | f3 = 072.40 82 | f4 = 2.71828 83 | f5 = 1.e+0 84 | f6 = 6.67428e-11 85 | f7 = 1E6 86 | f8 = .25 87 | f9 = .12345E+5 88 | f10 = 1_5. 89 | f11 = 0.15e+0_2 90 | f12 = 0x1p-2 91 | f13 = 0x2.p10 92 | f14 = 0x1.Fp+0 93 | f15 = 0X.8p-0 94 | f16 = 0X_1FFFP-16 95 | ) 96 | 97 | -------------------------------------------------------------------------------- 98 | 99 | (source_file 100 | (package_clause 101 | (package_identifier)) 102 | (const_declaration 103 | (const_spec 104 | (identifier) 105 | (expression_list 106 | (float_literal))) 107 | (const_spec 108 | (identifier) 109 | (expression_list 110 | (float_literal))) 111 | (const_spec 112 | (identifier) 113 | (expression_list 114 | (float_literal))) 115 | (const_spec 116 | (identifier) 117 | (expression_list 118 | (float_literal))) 119 | (const_spec 120 | (identifier) 121 | (expression_list 122 | (float_literal))) 123 | (const_spec 124 | (identifier) 125 | (expression_list 126 | (float_literal))) 127 | (const_spec 128 | (identifier) 129 | (expression_list 130 | (float_literal))) 131 | (const_spec 132 | (identifier) 133 | (expression_list 134 | (float_literal))) 135 | (const_spec 136 | (identifier) 137 | (expression_list 138 | (float_literal))) 139 | (const_spec 140 | (identifier) 141 | (expression_list 142 | (float_literal))) 143 | (const_spec 144 | (identifier) 145 | (expression_list 146 | (float_literal))) 147 | (const_spec 148 | (identifier) 149 | (expression_list 150 | (float_literal))) 151 | (const_spec 152 | (identifier) 153 | (expression_list 154 | (float_literal))) 155 | (const_spec 156 | (identifier) 157 | (expression_list 158 | (float_literal))) 159 | (const_spec 160 | (identifier) 161 | (expression_list 162 | (float_literal))) 163 | (const_spec 164 | (identifier) 165 | (expression_list 166 | (float_literal))))) 167 | 168 | ================================================================================ 169 | Rune literals 170 | ================================================================================ 171 | 172 | package main 173 | 174 | const ( 175 | a = '0' 176 | b = '\'' 177 | c = '\\' 178 | c = '\n' 179 | c = '\u0000' 180 | c = '\U01234567' 181 | ) 182 | 183 | -------------------------------------------------------------------------------- 184 | 185 | (source_file 186 | (package_clause 187 | (package_identifier)) 188 | (const_declaration 189 | (const_spec 190 | (identifier) 191 | (expression_list 192 | (rune_literal))) 193 | (const_spec 194 | (identifier) 195 | (expression_list 196 | (rune_literal))) 197 | (const_spec 198 | (identifier) 199 | (expression_list 200 | (rune_literal))) 201 | (const_spec 202 | (identifier) 203 | (expression_list 204 | (rune_literal))) 205 | (const_spec 206 | (identifier) 207 | (expression_list 208 | (rune_literal))) 209 | (const_spec 210 | (identifier) 211 | (expression_list 212 | (rune_literal))))) 213 | 214 | ================================================================================ 215 | Imaginary literals 216 | ================================================================================ 217 | 218 | package main 219 | 220 | const ( 221 | a = 0i 222 | b = 0123i 223 | c = 0o123i 224 | d = 0xabci 225 | e = 0.i 226 | f = 2.71828i 227 | g = 1.e+0i 228 | h = 6.67428e-11i 229 | i = 1E6i 230 | j = .25i 231 | k = .12345E+5i 232 | l = 0x1p-2i 233 | ) 234 | 235 | -------------------------------------------------------------------------------- 236 | 237 | (source_file 238 | (package_clause 239 | (package_identifier)) 240 | (const_declaration 241 | (const_spec 242 | (identifier) 243 | (expression_list 244 | (imaginary_literal))) 245 | (const_spec 246 | (identifier) 247 | (expression_list 248 | (imaginary_literal))) 249 | (const_spec 250 | (identifier) 251 | (expression_list 252 | (imaginary_literal))) 253 | (const_spec 254 | (identifier) 255 | (expression_list 256 | (imaginary_literal))) 257 | (const_spec 258 | (identifier) 259 | (expression_list 260 | (imaginary_literal))) 261 | (const_spec 262 | (identifier) 263 | (expression_list 264 | (imaginary_literal))) 265 | (const_spec 266 | (identifier) 267 | (expression_list 268 | (imaginary_literal))) 269 | (const_spec 270 | (identifier) 271 | (expression_list 272 | (imaginary_literal))) 273 | (const_spec 274 | (identifier) 275 | (expression_list 276 | (imaginary_literal))) 277 | (const_spec 278 | (identifier) 279 | (expression_list 280 | (imaginary_literal))) 281 | (const_spec 282 | (identifier) 283 | (expression_list 284 | (imaginary_literal))) 285 | (const_spec 286 | (identifier) 287 | (expression_list 288 | (imaginary_literal))))) 289 | 290 | ================================================================================ 291 | String literals 292 | ================================================================================ 293 | 294 | package main 295 | 296 | const ( 297 | a = "0" 298 | b = "`\"`" 299 | c = "\x0c" 300 | d = `//` 301 | e = "errorstring 302 | " 303 | ) 304 | 305 | -------------------------------------------------------------------------------- 306 | 307 | (source_file 308 | (package_clause 309 | (package_identifier)) 310 | (const_declaration 311 | (const_spec 312 | (identifier) 313 | (expression_list 314 | (interpreted_string_literal 315 | (interpreted_string_literal_content)))) 316 | (const_spec 317 | (identifier) 318 | (expression_list 319 | (interpreted_string_literal 320 | (interpreted_string_literal_content) 321 | (escape_sequence) 322 | (interpreted_string_literal_content)))) 323 | (const_spec 324 | (identifier) 325 | (expression_list 326 | (interpreted_string_literal 327 | (escape_sequence)))) 328 | (const_spec 329 | (identifier) 330 | (expression_list 331 | (raw_string_literal 332 | (raw_string_literal_content)))) 333 | (ERROR 334 | (identifier) 335 | (interpreted_string_literal_content)))) 336 | 337 | ================================================================================ 338 | Slice literals 339 | ================================================================================ 340 | 341 | package main 342 | 343 | const s1 = []string{} 344 | 345 | const s2 = []string{"hi"} 346 | 347 | const s3 = []string{ 348 | "hi", 349 | "hello", 350 | } 351 | 352 | -------------------------------------------------------------------------------- 353 | 354 | (source_file 355 | (package_clause 356 | (package_identifier)) 357 | (const_declaration 358 | (const_spec 359 | (identifier) 360 | (expression_list 361 | (composite_literal 362 | (slice_type 363 | (type_identifier)) 364 | (literal_value))))) 365 | (const_declaration 366 | (const_spec 367 | (identifier) 368 | (expression_list 369 | (composite_literal 370 | (slice_type 371 | (type_identifier)) 372 | (literal_value 373 | (literal_element 374 | (interpreted_string_literal 375 | (interpreted_string_literal_content)))))))) 376 | (const_declaration 377 | (const_spec 378 | (identifier) 379 | (expression_list 380 | (composite_literal 381 | (slice_type 382 | (type_identifier)) 383 | (literal_value 384 | (literal_element 385 | (interpreted_string_literal 386 | (interpreted_string_literal_content))) 387 | (literal_element 388 | (interpreted_string_literal 389 | (interpreted_string_literal_content))))))))) 390 | 391 | ================================================================================ 392 | Array literals with implicit length 393 | ================================================================================ 394 | 395 | package main 396 | 397 | const a1 = [...]int{1, 2, 3} 398 | 399 | -------------------------------------------------------------------------------- 400 | 401 | (source_file 402 | (package_clause 403 | (package_identifier)) 404 | (const_declaration 405 | (const_spec 406 | (identifier) 407 | (expression_list 408 | (composite_literal 409 | (implicit_length_array_type 410 | (type_identifier)) 411 | (literal_value 412 | (literal_element 413 | (int_literal)) 414 | (literal_element 415 | (int_literal)) 416 | (literal_element 417 | (int_literal)))))))) 418 | 419 | ================================================================================ 420 | Map literals 421 | ================================================================================ 422 | 423 | package main 424 | 425 | const s = map[string]string{ 426 | "hi": "hello", 427 | "bye": "goodbye", 428 | } 429 | 430 | -------------------------------------------------------------------------------- 431 | 432 | (source_file 433 | (package_clause 434 | (package_identifier)) 435 | (const_declaration 436 | (const_spec 437 | (identifier) 438 | (expression_list 439 | (composite_literal 440 | (map_type 441 | (type_identifier) 442 | (type_identifier)) 443 | (literal_value 444 | (keyed_element 445 | (literal_element 446 | (interpreted_string_literal 447 | (interpreted_string_literal_content))) 448 | (literal_element 449 | (interpreted_string_literal 450 | (interpreted_string_literal_content)))) 451 | (keyed_element 452 | (literal_element 453 | (interpreted_string_literal 454 | (interpreted_string_literal_content))) 455 | (literal_element 456 | (interpreted_string_literal 457 | (interpreted_string_literal_content)))))))))) 458 | 459 | ================================================================================ 460 | Struct literals 461 | ================================================================================ 462 | 463 | package main 464 | 465 | const s1 = Person{ 466 | name: "Frank", 467 | Age: "5 months", 468 | } 469 | 470 | const s2 = struct{i int;}{i: 5} 471 | 472 | const s3 = time.Time{} 473 | 474 | const g1 = Foo[float64, Bar[int]] { } 475 | 476 | -------------------------------------------------------------------------------- 477 | 478 | (source_file 479 | (package_clause 480 | (package_identifier)) 481 | (const_declaration 482 | (const_spec 483 | (identifier) 484 | (expression_list 485 | (composite_literal 486 | (type_identifier) 487 | (literal_value 488 | (keyed_element 489 | (literal_element 490 | (identifier)) 491 | (literal_element 492 | (interpreted_string_literal 493 | (interpreted_string_literal_content)))) 494 | (keyed_element 495 | (literal_element 496 | (identifier)) 497 | (literal_element 498 | (interpreted_string_literal 499 | (interpreted_string_literal_content))))))))) 500 | (const_declaration 501 | (const_spec 502 | (identifier) 503 | (expression_list 504 | (composite_literal 505 | (struct_type 506 | (field_declaration_list 507 | (field_declaration 508 | (field_identifier) 509 | (type_identifier)))) 510 | (literal_value 511 | (keyed_element 512 | (literal_element 513 | (identifier)) 514 | (literal_element 515 | (int_literal)))))))) 516 | (const_declaration 517 | (const_spec 518 | (identifier) 519 | (expression_list 520 | (composite_literal 521 | (qualified_type 522 | (package_identifier) 523 | (type_identifier)) 524 | (literal_value))))) 525 | (const_declaration 526 | (const_spec 527 | (identifier) 528 | (expression_list 529 | (composite_literal 530 | (generic_type 531 | (type_identifier) 532 | (type_arguments 533 | (type_elem 534 | (type_identifier)) 535 | (type_elem 536 | (generic_type 537 | (type_identifier) 538 | (type_arguments 539 | (type_elem 540 | (type_identifier))))))) 541 | (literal_value)))))) 542 | 543 | ================================================================================ 544 | Function literals 545 | ================================================================================ 546 | 547 | package main 548 | 549 | const s1 = func(s string) (int, int) { 550 | return 1, 2 551 | } 552 | 553 | -------------------------------------------------------------------------------- 554 | 555 | (source_file 556 | (package_clause 557 | (package_identifier)) 558 | (const_declaration 559 | (const_spec 560 | (identifier) 561 | (expression_list 562 | (func_literal 563 | (parameter_list 564 | (parameter_declaration 565 | (identifier) 566 | (type_identifier))) 567 | (parameter_list 568 | (parameter_declaration 569 | (type_identifier)) 570 | (parameter_declaration 571 | (type_identifier))) 572 | (block 573 | (return_statement 574 | (expression_list 575 | (int_literal) 576 | (int_literal))))))))) 577 | -------------------------------------------------------------------------------- /test/corpus/source_files.txt: -------------------------------------------------------------------------------- 1 | ============================================ 2 | Package clauses 3 | ============================================ 4 | 5 | package main 6 | 7 | ---- 8 | 9 | (source_file 10 | (package_clause 11 | (package_identifier))) 12 | 13 | ============================================ 14 | Single import declarations 15 | ============================================ 16 | 17 | package a 18 | 19 | import "net/http" 20 | import . "some/dsl" 21 | import _ "os" 22 | import alias "some/package" 23 | 24 | ---- 25 | 26 | (source_file 27 | (package_clause 28 | (package_identifier)) 29 | (import_declaration 30 | (import_spec 31 | (interpreted_string_literal 32 | (interpreted_string_literal_content)))) 33 | (import_declaration 34 | (import_spec 35 | (dot) 36 | (interpreted_string_literal 37 | (interpreted_string_literal_content)))) 38 | (import_declaration 39 | (import_spec 40 | (blank_identifier) 41 | (interpreted_string_literal 42 | (interpreted_string_literal_content)))) 43 | (import_declaration 44 | (import_spec 45 | (package_identifier) 46 | (interpreted_string_literal 47 | (interpreted_string_literal_content))))) 48 | 49 | ============================================ 50 | Grouped import declarations 51 | ============================================ 52 | 53 | package a 54 | 55 | import() 56 | import ("fmt") 57 | import ( 58 | "net/http" 59 | . "some/dsl" 60 | _ "os" 61 | alias "some/package" 62 | ) 63 | 64 | ---- 65 | 66 | (source_file 67 | (package_clause 68 | (package_identifier)) 69 | (import_declaration 70 | (import_spec_list)) 71 | (import_declaration 72 | (import_spec_list 73 | (import_spec 74 | (interpreted_string_literal 75 | (interpreted_string_literal_content))))) 76 | (import_declaration 77 | (import_spec_list 78 | (import_spec 79 | (interpreted_string_literal 80 | (interpreted_string_literal_content))) 81 | (import_spec 82 | (dot) 83 | (interpreted_string_literal 84 | (interpreted_string_literal_content))) 85 | (import_spec 86 | (blank_identifier) 87 | (interpreted_string_literal 88 | (interpreted_string_literal_content))) 89 | (import_spec 90 | (package_identifier) 91 | (interpreted_string_literal 92 | (interpreted_string_literal_content)))))) 93 | 94 | ============================================ 95 | Block comments 96 | ============================================ 97 | 98 | /* 99 | * This is a great package 100 | */ 101 | package a 102 | 103 | ---- 104 | 105 | (source_file 106 | (comment) 107 | (package_clause 108 | (package_identifier))) 109 | 110 | ============================================ 111 | Comments with asterisks 112 | ============================================ 113 | 114 | package main 115 | 116 | /* a */ 117 | const a 118 | 119 | /* b **/ 120 | const b 121 | 122 | /* c ***/ 123 | const c 124 | 125 | /* d 126 | 127 | ***/ 128 | const d 129 | 130 | --- 131 | 132 | (source_file 133 | (package_clause 134 | (package_identifier)) 135 | (comment) 136 | (const_declaration 137 | (const_spec 138 | (identifier))) 139 | (comment) 140 | (const_declaration 141 | (const_spec 142 | (identifier))) 143 | (comment) 144 | (const_declaration 145 | (const_spec 146 | (identifier))) 147 | (comment) 148 | (const_declaration 149 | (const_spec 150 | (identifier)))) 151 | 152 | ============================================ 153 | Non-ascii variable names 154 | ============================================ 155 | 156 | package main 157 | 158 | const ( 159 | α 160 | Α 161 | µs // micro sign (not mu) 162 | δ1 163 | ΔΔΔ 164 | ω_omega 165 | Ω_OMEGA 166 | ) 167 | 168 | --- 169 | 170 | (source_file 171 | (package_clause 172 | (package_identifier)) 173 | (const_declaration 174 | (const_spec 175 | (identifier)) 176 | (const_spec 177 | (identifier)) 178 | (const_spec 179 | (identifier)) 180 | (comment) 181 | (const_spec 182 | (identifier)) 183 | (const_spec 184 | (identifier)) 185 | (const_spec 186 | (identifier)) 187 | (const_spec 188 | (identifier)))) 189 | -------------------------------------------------------------------------------- /test/corpus/statements.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Declaration statements 3 | ================================================================================ 4 | 5 | package main 6 | 7 | func main() { 8 | var x = y 9 | const x = 5 10 | } 11 | 12 | -------------------------------------------------------------------------------- 13 | 14 | (source_file 15 | (package_clause 16 | (package_identifier)) 17 | (function_declaration 18 | (identifier) 19 | (parameter_list) 20 | (block 21 | (var_declaration 22 | (var_spec 23 | (identifier) 24 | (expression_list 25 | (identifier)))) 26 | (const_declaration 27 | (const_spec 28 | (identifier) 29 | (expression_list 30 | (int_literal))))))) 31 | 32 | ================================================================================ 33 | Expression statements 34 | ================================================================================ 35 | 36 | package main 37 | 38 | func main() { 39 | foo(5) 40 | } 41 | 42 | -------------------------------------------------------------------------------- 43 | 44 | (source_file 45 | (package_clause 46 | (package_identifier)) 47 | (function_declaration 48 | (identifier) 49 | (parameter_list) 50 | (block 51 | (expression_statement 52 | (call_expression 53 | (identifier) 54 | (argument_list 55 | (int_literal))))))) 56 | 57 | ================================================================================ 58 | Send statements 59 | ================================================================================ 60 | 61 | package main 62 | 63 | func main() { 64 | foo <- 5 65 | } 66 | 67 | -------------------------------------------------------------------------------- 68 | 69 | (source_file 70 | (package_clause 71 | (package_identifier)) 72 | (function_declaration 73 | (identifier) 74 | (parameter_list) 75 | (block 76 | (send_statement 77 | (identifier) 78 | (int_literal))))) 79 | 80 | ================================================================================ 81 | Increment/Decrement statements 82 | ================================================================================ 83 | 84 | package main 85 | 86 | func main() { 87 | i++ 88 | j-- 89 | } 90 | 91 | -------------------------------------------------------------------------------- 92 | 93 | (source_file 94 | (package_clause 95 | (package_identifier)) 96 | (function_declaration 97 | (identifier) 98 | (parameter_list) 99 | (block 100 | (inc_statement 101 | (identifier)) 102 | (dec_statement 103 | (identifier))))) 104 | 105 | ================================================================================ 106 | Assignment statements 107 | ================================================================================ 108 | 109 | package main 110 | 111 | func main() { 112 | a = 1 113 | b, c += 2, 3 114 | d *= 3 115 | e += 1 116 | f /= 2 117 | g <<= 1 118 | h >>= 1 119 | i %= 1 120 | j &= 2 121 | k &^= 3 122 | l -= 1 123 | m |= 2 124 | n ^= 2 125 | } 126 | 127 | -------------------------------------------------------------------------------- 128 | 129 | (source_file 130 | (package_clause 131 | (package_identifier)) 132 | (function_declaration 133 | (identifier) 134 | (parameter_list) 135 | (block 136 | (assignment_statement 137 | (expression_list 138 | (identifier)) 139 | (expression_list 140 | (int_literal))) 141 | (assignment_statement 142 | (expression_list 143 | (identifier) 144 | (identifier)) 145 | (expression_list 146 | (int_literal) 147 | (int_literal))) 148 | (assignment_statement 149 | (expression_list 150 | (identifier)) 151 | (expression_list 152 | (int_literal))) 153 | (assignment_statement 154 | (expression_list 155 | (identifier)) 156 | (expression_list 157 | (int_literal))) 158 | (assignment_statement 159 | (expression_list 160 | (identifier)) 161 | (expression_list 162 | (int_literal))) 163 | (assignment_statement 164 | (expression_list 165 | (identifier)) 166 | (expression_list 167 | (int_literal))) 168 | (assignment_statement 169 | (expression_list 170 | (identifier)) 171 | (expression_list 172 | (int_literal))) 173 | (assignment_statement 174 | (expression_list 175 | (identifier)) 176 | (expression_list 177 | (int_literal))) 178 | (assignment_statement 179 | (expression_list 180 | (identifier)) 181 | (expression_list 182 | (int_literal))) 183 | (assignment_statement 184 | (expression_list 185 | (identifier)) 186 | (expression_list 187 | (int_literal))) 188 | (assignment_statement 189 | (expression_list 190 | (identifier)) 191 | (expression_list 192 | (int_literal))) 193 | (assignment_statement 194 | (expression_list 195 | (identifier)) 196 | (expression_list 197 | (int_literal))) 198 | (assignment_statement 199 | (expression_list 200 | (identifier)) 201 | (expression_list 202 | (int_literal)))))) 203 | 204 | ================================================================================ 205 | Short var declarations 206 | ================================================================================ 207 | 208 | package main 209 | 210 | func main() { 211 | a, b := 1, 2 212 | } 213 | 214 | -------------------------------------------------------------------------------- 215 | 216 | (source_file 217 | (package_clause 218 | (package_identifier)) 219 | (function_declaration 220 | (identifier) 221 | (parameter_list) 222 | (block 223 | (short_var_declaration 224 | (expression_list 225 | (identifier) 226 | (identifier)) 227 | (expression_list 228 | (int_literal) 229 | (int_literal)))))) 230 | 231 | ================================================================================ 232 | If statements 233 | ================================================================================ 234 | 235 | package main 236 | 237 | func main() { 238 | if a { 239 | b() 240 | } 241 | 242 | if a := b(); c { 243 | d() 244 | } 245 | 246 | if a { 247 | b() 248 | } else { 249 | c() 250 | } 251 | 252 | if b { 253 | c() 254 | } else if d { 255 | e() 256 | } else { 257 | f() 258 | } 259 | } 260 | 261 | -------------------------------------------------------------------------------- 262 | 263 | (source_file 264 | (package_clause 265 | (package_identifier)) 266 | (function_declaration 267 | name: (identifier) 268 | parameters: (parameter_list) 269 | body: (block 270 | (if_statement 271 | condition: (identifier) 272 | consequence: (block 273 | (expression_statement 274 | (call_expression 275 | function: (identifier) 276 | arguments: (argument_list))))) 277 | (if_statement 278 | initializer: (short_var_declaration 279 | left: (expression_list 280 | (identifier)) 281 | right: (expression_list 282 | (call_expression 283 | function: (identifier) 284 | arguments: (argument_list)))) 285 | condition: (identifier) 286 | consequence: (block 287 | (expression_statement 288 | (call_expression 289 | function: (identifier) 290 | arguments: (argument_list))))) 291 | (if_statement 292 | condition: (identifier) 293 | consequence: (block 294 | (expression_statement 295 | (call_expression 296 | function: (identifier) 297 | arguments: (argument_list)))) 298 | alternative: (block 299 | (expression_statement 300 | (call_expression 301 | function: (identifier) 302 | arguments: (argument_list))))) 303 | (if_statement 304 | condition: (identifier) 305 | consequence: (block 306 | (expression_statement 307 | (call_expression 308 | function: (identifier) 309 | arguments: (argument_list)))) 310 | alternative: (if_statement 311 | condition: (identifier) 312 | consequence: (block 313 | (expression_statement 314 | (call_expression 315 | function: (identifier) 316 | arguments: (argument_list)))) 317 | alternative: (block 318 | (expression_statement 319 | (call_expression 320 | function: (identifier) 321 | arguments: (argument_list))))))))) 322 | 323 | ================================================================================ 324 | For statements 325 | ================================================================================ 326 | 327 | package main 328 | 329 | func main() { 330 | for { 331 | a() 332 | goto loop 333 | } 334 | 335 | loop: for i := 0; i < 5; i++ { 336 | a() 337 | break loop 338 | } 339 | 340 | loop2: 341 | for ; i < 10; i++ { 342 | a() 343 | continue loop2 344 | } 345 | 346 | for ;; { 347 | a() 348 | continue 349 | } 350 | 351 | for x := range y { 352 | a(x) 353 | break 354 | } 355 | } 356 | 357 | -------------------------------------------------------------------------------- 358 | 359 | (source_file 360 | (package_clause 361 | (package_identifier)) 362 | (function_declaration 363 | (identifier) 364 | (parameter_list) 365 | (block 366 | (for_statement 367 | (block 368 | (expression_statement 369 | (call_expression 370 | (identifier) 371 | (argument_list))) 372 | (goto_statement 373 | (label_name)))) 374 | (labeled_statement 375 | (label_name) 376 | (for_statement 377 | (for_clause 378 | (short_var_declaration 379 | (expression_list 380 | (identifier)) 381 | (expression_list 382 | (int_literal))) 383 | (binary_expression 384 | (identifier) 385 | (int_literal)) 386 | (inc_statement 387 | (identifier))) 388 | (block 389 | (expression_statement 390 | (call_expression 391 | (identifier) 392 | (argument_list))) 393 | (break_statement 394 | (label_name))))) 395 | (labeled_statement 396 | (label_name) 397 | (for_statement 398 | (for_clause 399 | (binary_expression 400 | (identifier) 401 | (int_literal)) 402 | (inc_statement 403 | (identifier))) 404 | (block 405 | (expression_statement 406 | (call_expression 407 | (identifier) 408 | (argument_list))) 409 | (continue_statement 410 | (label_name))))) 411 | (for_statement 412 | (for_clause) 413 | (block 414 | (expression_statement 415 | (call_expression 416 | (identifier) 417 | (argument_list))) 418 | (continue_statement))) 419 | (for_statement 420 | (range_clause 421 | (expression_list 422 | (identifier)) 423 | (identifier)) 424 | (block 425 | (expression_statement 426 | (call_expression 427 | (identifier) 428 | (argument_list 429 | (identifier)))) 430 | (break_statement)))))) 431 | 432 | ================================================================================ 433 | Switch statements 434 | ================================================================================ 435 | 436 | func main() { 437 | switch e { 438 | case 1, 2: 439 | a() 440 | fallthrough 441 | case 3: 442 | d() 443 | default: 444 | c() 445 | break 446 | } 447 | 448 | switch { 449 | case true: 450 | return 451 | } 452 | 453 | switch f := y(); f { 454 | } 455 | } 456 | 457 | -------------------------------------------------------------------------------- 458 | 459 | (source_file 460 | (function_declaration 461 | name: (identifier) 462 | parameters: (parameter_list) 463 | body: (block 464 | (expression_switch_statement 465 | value: (identifier) 466 | (expression_case 467 | value: (expression_list 468 | (int_literal) 469 | (int_literal)) 470 | (expression_statement 471 | (call_expression 472 | function: (identifier) 473 | arguments: (argument_list))) 474 | (fallthrough_statement)) 475 | (expression_case 476 | value: (expression_list 477 | (int_literal)) 478 | (expression_statement 479 | (call_expression 480 | function: (identifier) 481 | arguments: (argument_list)))) 482 | (default_case 483 | (expression_statement 484 | (call_expression 485 | function: (identifier) 486 | arguments: (argument_list))) 487 | (break_statement))) 488 | (expression_switch_statement 489 | (expression_case 490 | value: (expression_list 491 | (true)) 492 | (return_statement))) 493 | (expression_switch_statement 494 | initializer: (short_var_declaration 495 | left: (expression_list 496 | (identifier)) 497 | right: (expression_list 498 | (call_expression 499 | function: (identifier) 500 | arguments: (argument_list)))) 501 | value: (identifier))))) 502 | 503 | ================================================================================ 504 | Type switch statements 505 | ================================================================================ 506 | 507 | func main() { 508 | switch e.(type) { 509 | case []Person: 510 | a() 511 | case *Dog: 512 | break 513 | } 514 | switch i := x.(type) { 515 | case nil: 516 | printString("x is nil") 517 | case int: 518 | printInt(i) 519 | case float64: 520 | printFloat64(i) 521 | case func(int) float64: 522 | printFunction(i) 523 | case bool, string: 524 | printString("type is bool or string") 525 | default: 526 | printString("don't know the type") 527 | } 528 | } 529 | 530 | -------------------------------------------------------------------------------- 531 | 532 | (source_file 533 | (function_declaration 534 | name: (identifier) 535 | parameters: (parameter_list) 536 | body: (block 537 | (type_switch_statement 538 | value: (identifier) 539 | (type_case 540 | type: (slice_type 541 | element: (type_identifier)) 542 | (expression_statement 543 | (call_expression 544 | function: (identifier) 545 | arguments: (argument_list)))) 546 | (type_case 547 | type: (pointer_type 548 | (type_identifier)) 549 | (break_statement))) 550 | (type_switch_statement 551 | alias: (expression_list 552 | (identifier)) 553 | value: (identifier) 554 | (type_case 555 | type: (type_identifier) 556 | (expression_statement 557 | (call_expression 558 | function: (identifier) 559 | arguments: (argument_list 560 | (interpreted_string_literal 561 | (interpreted_string_literal_content)))))) 562 | (type_case 563 | type: (type_identifier) 564 | (expression_statement 565 | (call_expression 566 | function: (identifier) 567 | arguments: (argument_list 568 | (identifier))))) 569 | (type_case 570 | type: (type_identifier) 571 | (expression_statement 572 | (call_expression 573 | function: (identifier) 574 | arguments: (argument_list 575 | (identifier))))) 576 | (type_case 577 | type: (function_type 578 | parameters: (parameter_list 579 | (parameter_declaration 580 | type: (type_identifier))) 581 | result: (type_identifier)) 582 | (expression_statement 583 | (call_expression 584 | function: (identifier) 585 | arguments: (argument_list 586 | (identifier))))) 587 | (type_case 588 | type: (type_identifier) 589 | type: (type_identifier) 590 | (expression_statement 591 | (call_expression 592 | function: (identifier) 593 | arguments: (argument_list 594 | (interpreted_string_literal 595 | (interpreted_string_literal_content)))))) 596 | (default_case 597 | (expression_statement 598 | (call_expression 599 | function: (identifier) 600 | arguments: (argument_list 601 | (interpreted_string_literal 602 | (interpreted_string_literal_content)))))))))) 603 | 604 | ================================================================================ 605 | Select statements 606 | ================================================================================ 607 | 608 | package main 609 | 610 | func main() { 611 | select { 612 | case x := <-c: 613 | println(x) 614 | case y <- c: 615 | println(5) 616 | case <-time.After(1): 617 | println(6) 618 | default: 619 | return 620 | } 621 | } 622 | 623 | -------------------------------------------------------------------------------- 624 | 625 | (source_file 626 | (package_clause 627 | (package_identifier)) 628 | (function_declaration 629 | name: (identifier) 630 | parameters: (parameter_list) 631 | body: (block 632 | (select_statement 633 | (communication_case 634 | communication: (receive_statement 635 | left: (expression_list 636 | (identifier)) 637 | right: (unary_expression 638 | operand: (identifier))) 639 | (expression_statement 640 | (call_expression 641 | function: (identifier) 642 | arguments: (argument_list 643 | (identifier))))) 644 | (communication_case 645 | communication: (send_statement 646 | channel: (identifier) 647 | value: (identifier)) 648 | (expression_statement 649 | (call_expression 650 | function: (identifier) 651 | arguments: (argument_list 652 | (int_literal))))) 653 | (communication_case 654 | communication: (receive_statement 655 | right: (unary_expression 656 | operand: (call_expression 657 | function: (selector_expression 658 | operand: (identifier) 659 | field: (field_identifier)) 660 | arguments: (argument_list 661 | (int_literal))))) 662 | (expression_statement 663 | (call_expression 664 | function: (identifier) 665 | arguments: (argument_list 666 | (int_literal))))) 667 | (default_case 668 | (return_statement)))))) 669 | 670 | ================================================================================ 671 | Go and defer statements 672 | ================================================================================ 673 | 674 | package main 675 | 676 | func main() { 677 | defer x.y() 678 | go x.y() 679 | } 680 | 681 | -------------------------------------------------------------------------------- 682 | 683 | (source_file 684 | (package_clause 685 | (package_identifier)) 686 | (function_declaration 687 | (identifier) 688 | (parameter_list) 689 | (block 690 | (defer_statement 691 | (call_expression 692 | (selector_expression 693 | (identifier) 694 | (field_identifier)) 695 | (argument_list))) 696 | (go_statement 697 | (call_expression 698 | (selector_expression 699 | (identifier) 700 | (field_identifier)) 701 | (argument_list)))))) 702 | 703 | ================================================================================ 704 | Nested statement blocks 705 | ================================================================================ 706 | 707 | func main() { 708 | { 709 | println("hi") 710 | } 711 | { 712 | println("bye") 713 | } 714 | } 715 | 716 | -------------------------------------------------------------------------------- 717 | 718 | (source_file 719 | (function_declaration 720 | (identifier) 721 | (parameter_list) 722 | (block 723 | (block 724 | (expression_statement 725 | (call_expression 726 | (identifier) 727 | (argument_list 728 | (interpreted_string_literal 729 | (interpreted_string_literal_content)))))) 730 | (block 731 | (expression_statement 732 | (call_expression 733 | (identifier) 734 | (argument_list 735 | (interpreted_string_literal 736 | (interpreted_string_literal_content))))))))) 737 | 738 | ================================================================================ 739 | Labels at the ends of statement blocks 740 | ================================================================================ 741 | 742 | func main() { 743 | { 744 | end_of_block: 745 | } 746 | } 747 | 748 | -------------------------------------------------------------------------------- 749 | 750 | (source_file 751 | (function_declaration 752 | name: (identifier) 753 | parameters: (parameter_list) 754 | body: (block 755 | (block 756 | (labeled_statement 757 | label: (label_name)))))) 758 | 759 | ================================================================================ 760 | Empty statements 761 | ================================================================================ 762 | 763 | package main 764 | 765 | func main() { 766 | ; 767 | } 768 | 769 | -------------------------------------------------------------------------------- 770 | 771 | (source_file 772 | (package_clause 773 | (package_identifier)) 774 | (function_declaration 775 | (identifier) 776 | (parameter_list) 777 | (block 778 | (empty_statement)))) 779 | 780 | ================================================================================ 781 | Nested control statements 782 | ================================================================================ 783 | 784 | package main 785 | 786 | func main() { 787 | for i, v := range vectors { 788 | func() { 789 | if v == v { 790 | fmt.Println("something: %v", vectors[i]) 791 | } 792 | }() 793 | } 794 | } 795 | 796 | -------------------------------------------------------------------------------- 797 | 798 | (source_file 799 | (package_clause 800 | (package_identifier)) 801 | (function_declaration 802 | (identifier) 803 | (parameter_list) 804 | (block 805 | (for_statement 806 | (range_clause 807 | (expression_list 808 | (identifier) 809 | (identifier)) 810 | (identifier)) 811 | (block 812 | (expression_statement 813 | (call_expression 814 | (func_literal 815 | (parameter_list) 816 | (block 817 | (if_statement 818 | (binary_expression 819 | (identifier) 820 | (identifier)) 821 | (block 822 | (expression_statement 823 | (call_expression 824 | (selector_expression 825 | (identifier) 826 | (field_identifier)) 827 | (argument_list 828 | (interpreted_string_literal 829 | (interpreted_string_literal_content)) 830 | (index_expression 831 | (identifier) 832 | (identifier))))))))) 833 | (argument_list)))))))) 834 | 835 | ================================================================================ 836 | Top-level statements 837 | ================================================================================ 838 | 839 | foo(5) 840 | x := T { a: b } 841 | 842 | -------------------------------------------------------------------------------- 843 | 844 | (source_file 845 | (expression_statement 846 | (call_expression 847 | (identifier) 848 | (argument_list 849 | (int_literal)))) 850 | (short_var_declaration 851 | (expression_list 852 | (identifier)) 853 | (expression_list 854 | (composite_literal 855 | (type_identifier) 856 | (literal_value 857 | (keyed_element 858 | (literal_element 859 | (identifier)) 860 | (literal_element 861 | (identifier)))))))) 862 | -------------------------------------------------------------------------------- /test/corpus/types.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Qualified type names 3 | ================================================================================ 4 | 5 | type a b.c 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source_file 10 | (type_declaration 11 | (type_spec 12 | name: (type_identifier) 13 | type: (qualified_type 14 | package: (package_identifier) 15 | name: (type_identifier))))) 16 | 17 | ================================================================================ 18 | Array types 19 | ================================================================================ 20 | 21 | type a [2+2]c 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | (source_file 26 | (type_declaration 27 | (type_spec 28 | name: (type_identifier) 29 | type: (array_type 30 | length: (binary_expression 31 | left: (int_literal) 32 | right: (int_literal)) 33 | element: (type_identifier))))) 34 | 35 | ================================================================================ 36 | Slice types 37 | ================================================================================ 38 | 39 | package main 40 | 41 | type a []c 42 | type b [][]d 43 | 44 | -------------------------------------------------------------------------------- 45 | 46 | (source_file 47 | (package_clause 48 | (package_identifier)) 49 | (type_declaration 50 | (type_spec 51 | (type_identifier) 52 | (slice_type 53 | (type_identifier)))) 54 | (type_declaration 55 | (type_spec 56 | (type_identifier) 57 | (slice_type 58 | (slice_type 59 | (type_identifier)))))) 60 | 61 | ================================================================================ 62 | Struct types 63 | ================================================================================ 64 | 65 | package main 66 | 67 | type s1 struct {} 68 | 69 | type s2 struct { Person } 70 | 71 | type s2 struct { 72 | f, g int 73 | } 74 | 75 | type s3 struct { 76 | // an embedded struct 77 | p.s1 78 | 79 | // a tag 80 | h int `json:"h"` 81 | } 82 | 83 | type g1 struct { 84 | normal Array[T] 85 | nested Array[Array[T]] 86 | } 87 | 88 | type g2[T, U any, V interface{}, W Foo[Bar[T]]] struct {} 89 | 90 | -------------------------------------------------------------------------------- 91 | 92 | (source_file 93 | (package_clause 94 | (package_identifier)) 95 | (type_declaration 96 | (type_spec 97 | (type_identifier) 98 | (struct_type 99 | (field_declaration_list)))) 100 | (type_declaration 101 | (type_spec 102 | (type_identifier) 103 | (struct_type 104 | (field_declaration_list 105 | (field_declaration 106 | (type_identifier)))))) 107 | (type_declaration 108 | (type_spec 109 | (type_identifier) 110 | (struct_type 111 | (field_declaration_list 112 | (field_declaration 113 | (field_identifier) 114 | (field_identifier) 115 | (type_identifier)))))) 116 | (type_declaration 117 | (type_spec 118 | (type_identifier) 119 | (struct_type 120 | (field_declaration_list 121 | (comment) 122 | (field_declaration 123 | (qualified_type 124 | (package_identifier) 125 | (type_identifier))) 126 | (comment) 127 | (field_declaration 128 | (field_identifier) 129 | (type_identifier) 130 | (raw_string_literal 131 | (raw_string_literal_content))))))) 132 | (type_declaration 133 | (type_spec 134 | (type_identifier) 135 | (struct_type 136 | (field_declaration_list 137 | (field_declaration 138 | (field_identifier) 139 | (generic_type 140 | (type_identifier) 141 | (type_arguments 142 | (type_elem 143 | (type_identifier))))) 144 | (field_declaration 145 | (field_identifier) 146 | (generic_type 147 | (type_identifier) 148 | (type_arguments 149 | (type_elem 150 | (generic_type 151 | (type_identifier) 152 | (type_arguments 153 | (type_elem 154 | (type_identifier)))))))))))) 155 | (type_declaration 156 | (type_spec 157 | (type_identifier) 158 | (type_parameter_list 159 | (type_parameter_declaration 160 | (identifier) 161 | (identifier) 162 | (type_constraint 163 | (type_identifier))) 164 | (type_parameter_declaration 165 | (identifier) 166 | (type_constraint 167 | (interface_type))) 168 | (type_parameter_declaration 169 | (identifier) 170 | (type_constraint 171 | (generic_type 172 | (type_identifier) 173 | (type_arguments 174 | (type_elem 175 | (generic_type 176 | (type_identifier) 177 | (type_arguments 178 | (type_elem 179 | (type_identifier)))))))))) 180 | (struct_type 181 | (field_declaration_list))))) 182 | 183 | ================================================================================ 184 | Interface types 185 | ================================================================================ 186 | 187 | package main 188 | 189 | type i1 interface {} 190 | 191 | type i1 interface { io.Reader } 192 | 193 | type i2 interface { 194 | i1 195 | io.Reader 196 | SomeMethod(s string) error 197 | OtherMethod(int, ...bool) bool 198 | } 199 | 200 | type SignedInteger interface { 201 | int | int8 | ~uint | ~uint8 202 | } 203 | 204 | -------------------------------------------------------------------------------- 205 | 206 | (source_file 207 | (package_clause 208 | (package_identifier)) 209 | (type_declaration 210 | (type_spec 211 | (type_identifier) 212 | (interface_type))) 213 | (type_declaration 214 | (type_spec 215 | (type_identifier) 216 | (interface_type 217 | (type_elem 218 | (qualified_type 219 | (package_identifier) 220 | (type_identifier)))))) 221 | (type_declaration 222 | (type_spec 223 | (type_identifier) 224 | (interface_type 225 | (type_elem 226 | (type_identifier)) 227 | (type_elem 228 | (qualified_type 229 | (package_identifier) 230 | (type_identifier))) 231 | (method_elem 232 | (field_identifier) 233 | (parameter_list 234 | (parameter_declaration 235 | (identifier) 236 | (type_identifier))) 237 | (type_identifier)) 238 | (method_elem 239 | (field_identifier) 240 | (parameter_list 241 | (parameter_declaration 242 | (type_identifier)) 243 | (variadic_parameter_declaration 244 | (type_identifier))) 245 | (type_identifier))))) 246 | (type_declaration 247 | (type_spec 248 | (type_identifier) 249 | (interface_type 250 | (type_elem 251 | (type_identifier) 252 | (type_identifier) 253 | (negated_type 254 | (type_identifier)) 255 | (negated_type 256 | (type_identifier))))))) 257 | 258 | ================================================================================ 259 | Interface embedded struct types 260 | ================================================================================ 261 | 262 | package main 263 | 264 | type NewEmbeddings interface { 265 | struct{ f int } 266 | ~struct{ f int } 267 | *struct{ f int } 268 | struct{ f int } | ~struct{ f int } 269 | struct{ f int } | string 270 | } 271 | 272 | -------------------------------------------------------------------------------- 273 | 274 | (source_file 275 | (package_clause 276 | (package_identifier)) 277 | (type_declaration 278 | (type_spec 279 | (type_identifier) 280 | (interface_type 281 | (type_elem 282 | (struct_type 283 | (field_declaration_list 284 | (field_declaration 285 | (field_identifier) 286 | (type_identifier))))) 287 | (type_elem 288 | (negated_type 289 | (struct_type 290 | (field_declaration_list 291 | (field_declaration 292 | (field_identifier) 293 | (type_identifier)))))) 294 | (type_elem 295 | (pointer_type 296 | (struct_type 297 | (field_declaration_list 298 | (field_declaration 299 | (field_identifier) 300 | (type_identifier)))))) 301 | (type_elem 302 | (struct_type 303 | (field_declaration_list 304 | (field_declaration 305 | (field_identifier) 306 | (type_identifier)))) 307 | (negated_type 308 | (struct_type 309 | (field_declaration_list 310 | (field_declaration 311 | (field_identifier) 312 | (type_identifier)))))) 313 | (type_elem 314 | (struct_type 315 | (field_declaration_list 316 | (field_declaration 317 | (field_identifier) 318 | (type_identifier)))) 319 | (type_identifier)))))) 320 | 321 | ================================================================================ 322 | Map types 323 | ================================================================================ 324 | 325 | package main 326 | 327 | type m1 map[string]error 328 | 329 | -------------------------------------------------------------------------------- 330 | 331 | (source_file 332 | (package_clause 333 | (package_identifier)) 334 | (type_declaration 335 | (type_spec 336 | (type_identifier) 337 | (map_type 338 | (type_identifier) 339 | (type_identifier))))) 340 | 341 | ================================================================================ 342 | Pointer types 343 | ================================================================================ 344 | 345 | package main 346 | 347 | type ( 348 | p1 *string 349 | p2 **p1 350 | ) 351 | 352 | -------------------------------------------------------------------------------- 353 | 354 | (source_file 355 | (package_clause 356 | (package_identifier)) 357 | (type_declaration 358 | (type_spec 359 | (type_identifier) 360 | (pointer_type 361 | (type_identifier))) 362 | (type_spec 363 | (type_identifier) 364 | (pointer_type 365 | (pointer_type 366 | (type_identifier)))))) 367 | 368 | ================================================================================ 369 | Channel types 370 | ================================================================================ 371 | 372 | package main 373 | 374 | type ( 375 | c1 chan<- chan int 376 | c2 chan<- chan<- struct{} 377 | c3 chan<- <-chan int 378 | ) 379 | 380 | -------------------------------------------------------------------------------- 381 | 382 | (source_file 383 | (package_clause 384 | (package_identifier)) 385 | (type_declaration 386 | (type_spec 387 | (type_identifier) 388 | (channel_type 389 | (channel_type 390 | (type_identifier)))) 391 | (type_spec 392 | (type_identifier) 393 | (channel_type 394 | (channel_type 395 | (struct_type 396 | (field_declaration_list))))) 397 | (type_spec 398 | (type_identifier) 399 | (channel_type 400 | (channel_type 401 | (type_identifier)))))) 402 | 403 | ================================================================================ 404 | Function types 405 | ================================================================================ 406 | 407 | package main 408 | 409 | type ( 410 | a func(int) int 411 | b func(int, *string) (bool, error) 412 | c func(int, ...*string) bool 413 | ) 414 | 415 | -------------------------------------------------------------------------------- 416 | 417 | (source_file 418 | (package_clause 419 | (package_identifier)) 420 | (type_declaration 421 | (type_spec 422 | (type_identifier) 423 | (function_type 424 | (parameter_list 425 | (parameter_declaration 426 | (type_identifier))) 427 | (type_identifier))) 428 | (type_spec 429 | (type_identifier) 430 | (function_type 431 | (parameter_list 432 | (parameter_declaration 433 | (type_identifier)) 434 | (parameter_declaration 435 | (pointer_type 436 | (type_identifier)))) 437 | (parameter_list 438 | (parameter_declaration 439 | (type_identifier)) 440 | (parameter_declaration 441 | (type_identifier))))) 442 | (type_spec 443 | (type_identifier) 444 | (function_type 445 | (parameter_list 446 | (parameter_declaration 447 | (type_identifier)) 448 | (variadic_parameter_declaration 449 | (pointer_type 450 | (type_identifier)))) 451 | (type_identifier))))) 452 | 453 | ================================================================================ 454 | Type Aliases 455 | ================================================================================ 456 | 457 | package main 458 | 459 | type H1 = G1 460 | type _ = G2 461 | type _ = struct{} 462 | type ( 463 | A0 = T0 464 | A1 = int 465 | A2 = struct{} 466 | A3 = reflect.Value 467 | A4 = Value 468 | A5 = Value 469 | ) 470 | 471 | -------------------------------------------------------------------------------- 472 | 473 | (source_file 474 | (package_clause 475 | (package_identifier)) 476 | (type_declaration 477 | (type_alias 478 | (type_identifier) 479 | (type_identifier))) 480 | (type_declaration 481 | (type_alias 482 | (type_identifier) 483 | (type_identifier))) 484 | (type_declaration 485 | (type_alias 486 | (type_identifier) 487 | (struct_type 488 | (field_declaration_list)))) 489 | (type_declaration 490 | (type_alias 491 | (type_identifier) 492 | (type_identifier)) 493 | (type_alias 494 | (type_identifier) 495 | (type_identifier)) 496 | (type_alias 497 | (type_identifier) 498 | (struct_type 499 | (field_declaration_list))) 500 | (type_alias 501 | (type_identifier) 502 | (qualified_type 503 | (package_identifier) 504 | (type_identifier))) 505 | (type_alias 506 | (type_identifier) 507 | (type_identifier)) 508 | (type_alias 509 | (type_identifier) 510 | (type_identifier)))) 511 | -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammars": [ 3 | { 4 | "name": "go", 5 | "camelcase": "Go", 6 | "scope": "source.go", 7 | "path": ".", 8 | "file-types": [ 9 | "go" 10 | ], 11 | "highlights": "queries/highlights.scm", 12 | "tags": "queries/tags.scm" 13 | } 14 | ], 15 | "metadata": { 16 | "version": "0.23.4", 17 | "license": "MIT", 18 | "description": "Go grammar for tree-sitter", 19 | "authors": [ 20 | { 21 | "name": "Max Brunsfeld", 22 | "email": "maxbrunsfeld@gmail.com" 23 | }, 24 | { 25 | "name": "Amaan Qureshi", 26 | "email": "amaanq12@gmail.com" 27 | } 28 | ], 29 | "links": { 30 | "repository": "https://github.com/tree-sitter/tree-sitter-go" 31 | } 32 | }, 33 | "bindings": { 34 | "c": true, 35 | "go": true, 36 | "node": true, 37 | "python": true, 38 | "rust": true, 39 | "swift": true 40 | } 41 | } 42 | --------------------------------------------------------------------------------