Merge commit 'bbaa67a180cfe0c943e50c55130918be8efb20bd'

syntax_id
Wilfred Hughes 2023-08-08 23:21:24 +07:00
commit 3eb014c0a7
29 changed files with 1737 additions and 1221 deletions

@ -2,7 +2,7 @@
### Parsing
Updated Erlang parser.
Updated Erlang and Go parsers.
### Display

@ -0,0 +1,21 @@
module.exports = {
'env': {
'commonjs': true,
'es2021': true,
},
'extends': 'google',
'overrides': [
],
'parserOptions': {
'ecmaVersion': 'latest',
'sourceType': 'module',
},
'rules': {
'indent': ['error', 2, {'SwitchCase': 1}],
'max-len': [
'error',
{'code': 160, 'ignoreComments': true, 'ignoreUrls': true, 'ignoreStrings': true},
],
'one-var': ['error', 'consecutive'],
},
};

@ -1,2 +1,6 @@
/src/** linguist-vendored
/examples/* linguist-vendored
src/grammar.json -diff
src/node-types.json -diff
src/parser.c -diff

@ -1,4 +1,4 @@
name: Build/test
name: CI
on:
pull_request: null
@ -14,18 +14,18 @@ jobs:
matrix:
os: [macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
- run: npm install
- run: npm test
test_windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
- run: npm install
- run: npm run-script test-windows

@ -0,0 +1,19 @@
name: Lint
on:
push:
branches:
- master
pull_request:
branches:
- "**"
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install modules
run: npm install
- name: Run ESLint
run: npm run lint

@ -0,0 +1,103 @@
name: Release
on:
workflow_run:
workflows: ["CI"]
branches:
- master
types:
- completed
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get previous commit SHA
id: get_previous_commit
run: |
LATEST_TAG=$(git describe --tags --abbrev=0)
if [[ -z "$LATEST_TAG" ]]; then
echo "No tag found. Failing..."
exit 1
fi
echo "latest_tag=${LATEST_TAG#v}" >> "$GITHUB_ENV" # Remove 'v' prefix from the tag
- name: Check if version changed and is greater than the previous
id: version_check
run: |
# Compare the current version with the version from the previous commit
PREVIOUS_NPM_VERSION=${{ env.latest_tag }}
CURRENT_NPM_VERSION=$(jq -r '.version' package.json)
CURRENT_CARGO_VERSION=$(awk -F '"' '/^version/ {print $2}' Cargo.toml)
if [[ "$CURRENT_NPM_VERSION" != "$CURRENT_CARGO_VERSION" ]]; then # Cargo.toml and package.json versions must match
echo "Mismatch: NPM version ($CURRENT_NPM_VERSION) and Cargo.toml version ($CURRENT_CARGO_VERSION)"
echo "version_changed=false" >> "$GITHUB_ENV"
else
if [[ "$PREVIOUS_NPM_VERSION" == "$CURRENT_NPM_VERSION" ]]; then
echo "version_changed=" >> "$GITHUB_ENV"
else
IFS='.' read -ra PREVIOUS_VERSION_PARTS <<< "$PREVIOUS_NPM_VERSION"
IFS='.' read -ra CURRENT_VERSION_PARTS <<< "$CURRENT_NPM_VERSION"
VERSION_CHANGED=false
for i in "${!PREVIOUS_VERSION_PARTS[@]}"; do
if [[ ${CURRENT_VERSION_PARTS[i]} -gt ${PREVIOUS_VERSION_PARTS[i]} ]]; then
VERSION_CHANGED=true
break
elif [[ ${CURRENT_VERSION_PARTS[i]} -lt ${PREVIOUS_VERSION_PARTS[i]} ]]; then
break
fi
done
echo "version_changed=$VERSION_CHANGED" >> "$GITHUB_ENV"
echo "current_version=${CURRENT_NPM_VERSION}" >> "$GITHUB_ENV"
fi
fi
- name: Display result
run: |
echo "Version bump detected: ${{ env.version_changed }}"
- name: Fail if version is lower
if: env.version_changed == 'false'
run: exit 1
- name: Setup Node
if: env.version_changed == 'true'
uses: actions/setup-node@v3
with:
node-version: 18
registry-url: "https://registry.npmjs.org"
- name: Publish to NPM
if: env.version_changed == 'true'
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: npm publish
- name: Setup Rust
if: env.version_changed == 'true'
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Publish to Crates.io
if: env.version_changed == 'true'
uses: katyo/publish-crates@v2
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Tag versions
if: env.version_changed == 'true'
run: |
git checkout master
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git tag -d "v${{ env.current_version }}" || true
git push origin --delete "v${{ env.current_version }}" || true
git tag -a "v${{ env.current_version }}" -m "Version ${{ env.current_version }}"
git push origin "v${{ env.current_version }}"

@ -1,7 +1,7 @@
[package]
name = "tree-sitter-go"
description = "Go grammar for the tree-sitter parsing library"
version = "0.19.1"
description = "Go grammar for tree-sitter"
version = "0.20.0"
authors = [
"Max Brunsfeld <maxbrunsfeld@gmail.com>",
"Douglas Creager <dcreager@dcreager.net>",
@ -12,20 +12,16 @@ keywords = ["incremental", "parsing", "go"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/tree-sitter/tree-sitter-go"
edition = "2018"
autoexamples = false
build = "bindings/rust/build.rs"
include = [
"bindings/rust/*",
"grammar.js",
"queries/*",
"src/*",
]
include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = ">= 0.19, < 0.21"
tree-sitter = ">= 0.20, < 0.21"
[build-dependencies]
cc = "1.0"

@ -1,4 +1,4 @@
VERSION := 0.19.1
VERSION := 0.20.0
# Repository
SRC_DIR := src

@ -1,7 +1,6 @@
tree-sitter-go
===========================
# tree-sitter-go
[![Build/test](https://github.com/tree-sitter/tree-sitter-go/actions/workflows/ci.yml/badge.svg)](https://github.com/tree-sitter/tree-sitter-go/actions/workflows/ci.yml)
[![CI](https://github.com/tree-sitter/tree-sitter-go/actions/workflows/ci.yml/badge.svg)](https://github.com/tree-sitter/tree-sitter-go/actions/workflows/ci.yml)
A [tree-sitter][] grammar for [Go](https://go.dev/ref/spec).

@ -1,10 +1,10 @@
#include "nan.h"
#include "tree_sitter/parser.h"
#include <node.h>
#include "nan.h"
using namespace v8;
extern "C" TSLanguage * tree_sitter_go();
extern "C" TSLanguage *tree_sitter_go();
namespace {
@ -16,10 +16,12 @@ void Init(Local<Object> exports, Local<Object> module) {
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
Local<Object> instance =
constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_go());
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("go").ToLocalChecked());
Nan::Set(instance, Nan::New("name").ToLocalChecked(),
Nan::New("go").ToLocalChecked());
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
}

@ -1,19 +1,19 @@
try {
module.exports = require("../../build/Release/tree_sitter_go_binding");
module.exports = require('../../build/Release/tree_sitter_go_binding');
} catch (error1) {
if (error1.code !== 'MODULE_NOT_FOUND') {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_go_binding");
module.exports = require('../../build/Debug/tree_sitter_go_binding');
} catch (error2) {
if (error2.code !== 'MODULE_NOT_FOUND') {
throw error2;
}
throw error1
throw error1;
}
}
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
module.exports.nodeTypeInfo = require('../../src/node-types.json');
} catch (_) {}

@ -6,16 +6,16 @@ file. (Note that you will probably also need to depend on the
[`tree-sitter`][tree-sitter crate] crate to use the parsed result in any useful
way.)
``` toml
```toml
[dependencies]
tree-sitter = "0.20"
tree-sitter-go = "0.19"
tree-sitter = "0.20.10"
tree-sitter-go = "0.20.0"
```
Typically, you will use the [language][language func] function to add this
Typically, you will use the [language][language] function to add this
grammar to a tree-sitter [Parser][], and then use the parser to parse some code:
``` rust
```rust
let code = r#"
func double(x int) int {
return x * 2
@ -29,8 +29,7 @@ let parsed = parser.parse(code, None);
If you have any questions, please reach out to us in the [tree-sitter
discussions] page.
[Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
[language func]: https://docs.rs/tree-sitter-go/*/tree_sitter_go/fn.language.html
[language]: https://docs.rs/tree-sitter-go/*/tree_sitter_go/fn.language.html
[Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
[tree-sitter]: https://tree-sitter.github.io/
[tree-sitter crate]: https://crates.io/crates/tree-sitter

@ -1,7 +1,7 @@
fn main() {
let src_dir = std::path::Path::new("src");
let mut c_config = cc::Build::new();
c_config.include(&src_dir);
c_config.include(src_dir);
c_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")

@ -19,10 +19,9 @@
//! "#;
//! let mut parser = Parser::new();
//! parser.set_language(tree_sitter_go::language()).expect("Error loading Go grammar");
//! let parsed = parser.parse(code, None);
//! # let parsed = parsed.unwrap();
//! # let root = parsed.root_node();
//! # assert!(!root.has_error());
//! let parsed = parser.parse(code, None).unwrap();
//! let root = parsed.root_node();
//! assert!(!root.has_error());
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
@ -44,18 +43,18 @@ pub fn language() -> Language {
}
/// The source of the Go tree-sitter grammar description.
pub const GRAMMAR: &'static str = include_str!("../../grammar.js");
pub const GRAMMAR: &str = include_str!("../../grammar.js");
/// The syntax highlighting query for this language.
pub const HIGHLIGHT_QUERY: &'static str = include_str!("../../queries/highlights.scm");
pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights.scm");
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
/// The symbol tagging query for this language.
pub const TAGGING_QUERY: &'static str = include_str!("../../queries/tags.scm");
pub const TAGGING_QUERY: &str = include_str!("../../queries/tags.scm");
#[cfg(test)]
mod tests {

@ -1,261 +0,0 @@
============================================
Call expressions
============================================
package main
func main() {
a(b, c...)
a(
b,
c,
)
a(
b,
c...,
)
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(call_expression
(identifier)
(argument_list
(identifier)
(variadic_argument (identifier))))
(call_expression
(identifier)
(argument_list (identifier) (identifier)))
(call_expression
(identifier)
(argument_list (identifier) (variadic_argument (identifier)))))))
============================================
Nested call expressions
============================================
package main
func main() {
a(b(c(d)))
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(call_expression (identifier) (argument_list
(call_expression (identifier) (argument_list
(call_expression (identifier) (argument_list
(identifier))))))))))
============================================
Generic call expressions
============================================
package main
func main() {
a[b](c)
a[b, c](d)
a[b[c], d](e[f])
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(call_expression
(identifier)
(type_arguments (type_identifier))
(argument_list (identifier)))
(call_expression
(identifier)
(type_arguments (type_identifier) (type_identifier))
(argument_list (identifier)))
(call_expression
(identifier)
(type_arguments
(generic_type (type_identifier) (type_arguments (type_identifier)))
(type_identifier))
(argument_list (index_expression (identifier) (identifier)))))))
============================================
Calls to 'make' and 'new'
============================================
package main
func main() {
make(chan<- int)
// `new` and `make` can also be used as variable names
make(chan<- int, (new - old), make.stuff)
make(chan<- int, 5, 10)
new(map[string]string)
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(call_expression
(identifier)
(argument_list (channel_type (type_identifier))))
(comment)
(call_expression
(identifier)
(argument_list
(channel_type (type_identifier))
(parenthesized_expression (binary_expression (identifier) (identifier)))
(selector_expression (identifier) (field_identifier))))
(call_expression
(identifier)
(argument_list
(channel_type (type_identifier))
(int_literal)
(int_literal)))
(call_expression
(identifier)
(argument_list
(map_type (type_identifier) (type_identifier)))))))
============================================
Selector expressions
============================================
package main
func main() {
a.b.c()
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(call_expression
(selector_expression
(selector_expression (identifier) (field_identifier))
(field_identifier))
(argument_list)))))
============================================
Indexing expressions
============================================
package main
func main() {
a[1]
b[:]
c[1:]
d[1:2]
e[:2:3]
f[1:2:3]
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(index_expression (identifier) (int_literal))
(slice_expression (identifier))
(slice_expression (identifier) (int_literal))
(slice_expression (identifier) (int_literal) (int_literal))
(slice_expression (identifier) (int_literal) (int_literal))
(slice_expression (identifier) (int_literal) (int_literal) (int_literal)))))
============================================
Type assertion expressions
============================================
package main
func main() {
a.(p.Person)
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(type_assertion_expression
(identifier)
(qualified_type (package_identifier) (type_identifier))))))
============================================
Type conversion expressions
============================================
package main
func main() {
[]a.b(c.d)
([]a.b)(c.d)
<-chan int(c)
// These type conversions cannot be distinguished from call expressions
T(x)
(*Point)(p)
e.f(g)
(e.f)(g)
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(type_conversion_expression
(slice_type (qualified_type (package_identifier) (type_identifier)))
(selector_expression (identifier) (field_identifier)))
(type_conversion_expression
(parenthesized_type (slice_type (qualified_type (package_identifier) (type_identifier))))
(selector_expression (identifier) (field_identifier)))
(type_conversion_expression
(channel_type (type_identifier)) (identifier))
(comment)
(call_expression
(identifier) (argument_list (identifier)))
(call_expression
(parenthesized_expression
(unary_expression (identifier)))
(argument_list (identifier)))
(call_expression
(selector_expression (identifier) (field_identifier))
(argument_list (identifier)))
(call_expression
(parenthesized_expression
(selector_expression (identifier) (field_identifier)))
(argument_list (identifier))))))
============================================
Unary expressions
============================================
package main
func main() {
!<-a
*foo()
}
---
(source_file
(package_clause (package_identifier))
(function_declaration (identifier) (parameter_list) (block
(unary_expression (unary_expression (identifier)))
(unary_expression (call_expression (identifier) (argument_list))))))

@ -1,3 +1,15 @@
/**
* @file Go grammar for tree-sitter
* @author Max Brunsfeld
* @license MIT
*/
/* eslint-disable arrow-parens */
/* eslint-disable camelcase */
/* eslint-disable-next-line spaced-comment */
/// <reference types="tree-sitter-cli/dsl" />
// @ts-check
const
PREC = {
primary: 7,
@ -15,14 +27,9 @@ const
comparative_operators = ['==', '!=', '<', '<=', '>', '>='],
assignment_operators = multiplicative_operators.concat(additive_operators).map(operator => operator + '=').concat('='),
unicodeLetter = /\p{L}/,
unicodeDigit = /[0-9]/,
unicodeChar = /./,
unicodeValue = unicodeChar,
letter = choice(unicodeLetter, '_'),
newline = '\n',
terminator = choice(newline, ';'),
terminator = choice(newline, ';', '\0'),
hexDigit = /[0-9a-fA-F]/,
octalDigit = /[0-7]/,
@ -58,14 +65,14 @@ const
floatLiteral = choice(decimalFloatLiteral, hexFloatLiteral),
imaginaryLiteral = seq(choice(decimalDigits, intLiteral, floatLiteral), 'i')
imaginaryLiteral = seq(choice(decimalDigits, intLiteral, floatLiteral), 'i');
module.exports = grammar({
name: 'go',
extras: $ => [
$.comment,
/\s/
/\s/,
],
inline: $ => [
@ -84,12 +91,9 @@ module.exports = grammar({
[$.qualified_type, $._expression],
[$.generic_type, $._expression],
[$.generic_type, $._simple_type],
[$.parameter_declaration, $.type_arguments],
[$.parameter_declaration, $._simple_type, $._expression],
[$.parameter_declaration, $.generic_type, $._expression],
[$.parameter_declaration, $._expression],
[$.func_literal, $.function_type],
[$.function_type],
[$.parameter_declaration, $._simple_type],
],
@ -102,57 +106,61 @@ module.exports = grammar({
],
rules: {
source_file: $ => repeat(choice(
source_file: $ => seq(
repeat(choice(
// Unlike a Go compiler, we accept statements at top-level to enable
// parsing of partial code snippets in documentation (see #63).
seq($._statement, terminator),
seq($._top_level_declaration, optional(terminator)),
seq($._top_level_declaration, terminator),
)),
optional($._top_level_declaration),
),
_top_level_declaration: $ => choice(
$.package_clause,
$.function_declaration,
$.method_declaration,
$.import_declaration
$.import_declaration,
),
package_clause: $ => seq(
'package',
$._package_identifier
$._package_identifier,
),
import_declaration: $ => seq(
'import',
choice(
$.import_spec,
$.import_spec_list
)
$.import_spec_list,
),
),
import_spec: $ => seq(
optional(field('name', choice(
$.dot,
$.blank_identifier,
$._package_identifier
$._package_identifier,
))),
field('path', $._string_literal)
field('path', $._string_literal),
),
dot: $ => '.',
blank_identifier: $ => '_',
dot: _ => '.',
blank_identifier: _ => '_',
import_spec_list: $ => seq(
'(',
repeat(seq(
optional(seq(
$.import_spec,
terminator
repeat(seq(terminator, $.import_spec)),
optional(terminator),
)),
')'
')',
),
_declaration: $ => choice(
$.const_declaration,
$.type_declaration,
$.var_declaration
$.var_declaration,
),
const_declaration: $ => seq(
@ -162,9 +170,9 @@ module.exports = grammar({
seq(
'(',
repeat(seq($.const_spec, terminator)),
')'
)
)
')',
),
),
),
const_spec: $ => prec.left(seq(
@ -172,8 +180,8 @@ module.exports = grammar({
optional(seq(
optional(field('type', $._type)),
'=',
field('value', $.expression_list)
))
field('value', $.expression_list),
)),
)),
var_declaration: $ => seq(
@ -183,9 +191,9 @@ module.exports = grammar({
seq(
'(',
repeat(seq($.var_spec, terminator)),
')'
)
)
')',
),
),
),
var_spec: $ => seq(
@ -193,10 +201,10 @@ module.exports = grammar({
choice(
seq(
field('type', $._type),
optional(seq('=', field('value', $.expression_list)))
optional(seq('=', field('value', $.expression_list))),
),
seq('=', field('value', $.expression_list)),
),
seq('=', field('value', $.expression_list))
)
),
function_declaration: $ => prec.right(1, seq(
@ -205,7 +213,7 @@ module.exports = grammar({
field('type_parameters', optional($.type_parameter_list)),
field('parameters', $.parameter_list),
field('result', optional(choice($.parameter_list, $._simple_type))),
field('body', optional($.block))
field('body', optional($.block)),
)),
method_declaration: $ => prec.right(1, seq(
@ -214,40 +222,40 @@ module.exports = grammar({
field('name', $._field_identifier),
field('parameters', $.parameter_list),
field('result', optional(choice($.parameter_list, $._simple_type))),
field('body', optional($.block))
field('body', optional($.block)),
)),
type_parameter_list: $ => seq(
'[',
commaSep1($.parameter_declaration),
optional(','),
']'
']',
),
parameter_list: $ => seq(
'(',
optional(seq(
commaSep(choice($.parameter_declaration, $.variadic_parameter_declaration)),
optional(',')
optional(','),
)),
')'
')',
),
parameter_declaration: $ => seq(
parameter_declaration: $ => prec.left(seq(
commaSep(field('name', $.identifier)),
field('type', $._type)
),
field('type', $._type),
)),
variadic_parameter_declaration: $ => seq(
field('name', optional($.identifier)),
'...',
field('type', $._type)
field('type', $._type),
),
type_alias: $ => seq(
field('name', $._type_identifier),
'=',
field('type', $._type)
field('type', $._type),
),
type_declaration: $ => seq(
@ -258,15 +266,15 @@ module.exports = grammar({
seq(
'(',
repeat(seq(choice($.type_spec, $.type_alias), terminator)),
')'
)
)
')',
),
),
),
type_spec: $ => seq(
field('name', $._type_identifier),
field('type_parameters', optional($.type_parameter_list)),
field('type', $._type)
field('type', $._type),
),
field_name_list: $ => commaSep1($._field_identifier),
@ -275,7 +283,7 @@ module.exports = grammar({
_type: $ => choice(
$._simple_type,
$.parenthesized_type
$.parenthesized_type,
),
parenthesized_type: $ => seq('(', $._type, ')'),
@ -291,11 +299,13 @@ module.exports = grammar({
$.slice_type,
$.map_type,
$.channel_type,
$.function_type
$.function_type,
$.union_type,
$.negated_type,
),
generic_type: $ => seq(
field('type', choice($._type_identifier, $.qualified_type)),
field('type', choice($._type_identifier, $.qualified_type, $.union_type, $.negated_type)),
field('type_arguments', $.type_arguments),
),
@ -303,61 +313,73 @@ module.exports = grammar({
'[',
commaSep1($._type),
optional(','),
']'
']',
)),
pointer_type: $ => prec(PREC.unary, seq('*', $._type)),
array_type: $ => seq(
array_type: $ => prec.right(seq(
'[',
field('length', $._expression),
']',
field('element', $._type)
),
field('element', $._type),
)),
implicit_length_array_type: $ => seq(
'[',
'...',
']',
field('element', $._type)
field('element', $._type),
),
slice_type: $ => seq(
slice_type: $ => prec.right(seq(
'[',
']',
field('element', $._type)
),
field('element', $._type),
)),
struct_type: $ => seq(
'struct',
$.field_declaration_list
$.field_declaration_list,
),
union_type: $ => prec.left(seq(
$._type,
'|',
$._type,
)),
negated_type: $ => prec.left(seq(
'~',
$._type,
)),
field_declaration_list: $ => seq(
'{',
optional(seq(
$.field_declaration,
repeat(seq(terminator, $.field_declaration)),
optional(terminator)
optional(terminator),
)),
'}'
'}',
),
field_declaration: $ => seq(
choice(
seq(
commaSep1(field('name', $._field_identifier)),
field('type', $._type)
field('type', $._type),
),
seq(
optional('*'),
field('type', choice(
$._type_identifier,
$.qualified_type
))
)
$.qualified_type,
$.generic_type,
)),
),
field('tag', optional($._string_literal))
),
field('tag', optional($._string_literal)),
),
interface_type: $ => seq(
@ -366,67 +388,57 @@ module.exports = grammar({
optional(seq(
$._interface_body,
repeat(seq(terminator, $._interface_body)),
optional(terminator)
optional(terminator),
)),
'}'
'}',
),
_interface_body: $ => choice(
$.method_spec, $.interface_type_name, $.constraint_elem, $.struct_elem
$.method_spec,
$.struct_elem,
alias($._simple_type, $.constraint_elem),
),
interface_type_name: $ => choice($._type_identifier, $.qualified_type),
constraint_elem: $ => seq(
$.constraint_term,
repeat(seq('|', $.constraint_term))
),
constraint_term: $ => prec(-1, seq(
optional('~'),
$._type_identifier,
)),
struct_elem: $ => seq(
$.struct_term,
repeat(seq('|', $.struct_term))
repeat(seq('|', $.struct_term)),
),
struct_term: $ => prec(-1, seq(
struct_term: $ => prec(1, seq(
optional(choice('~', '*')),
$.struct_type
$.struct_type,
)),
method_spec: $ => seq(
field('name', $._field_identifier),
field('parameters', $.parameter_list),
field('result', optional(choice($.parameter_list, $._simple_type)))
field('result', optional(choice($.parameter_list, $._simple_type))),
),
map_type: $ => seq(
map_type: $ => prec.right(seq(
'map',
'[',
field('key', $._type),
']',
field('value', $._type)
),
field('value', $._type),
)),
channel_type: $ => choice(
channel_type: $ => prec.left(choice(
seq('chan', field('value', $._type)),
seq('chan', '<-', field('value', $._type)),
prec(PREC.unary, seq('<-', 'chan', field('value', $._type)))
),
prec(PREC.unary, seq('<-', 'chan', field('value', $._type))),
)),
function_type: $ => seq(
function_type: $ => prec.right(seq(
'func',
field('parameters', $.parameter_list),
field('result', optional(choice($.parameter_list, $._simple_type)))
),
field('result', optional(choice($.parameter_list, $._simple_type))),
)),
block: $ => seq(
'{',
optional($._statement_list),
'}'
'}',
),
_statement_list: $ => choice(
@ -435,10 +447,10 @@ module.exports = grammar({
repeat(seq(terminator, $._statement)),
optional(seq(
terminator,
optional(alias($.empty_labeled_statement, $.labeled_statement))
))
optional(alias($.empty_labeled_statement, $.labeled_statement)),
)),
),
alias($.empty_labeled_statement, $.labeled_statement)
alias($.empty_labeled_statement, $.labeled_statement),
),
_statement: $ => choice(
@ -458,48 +470,50 @@ module.exports = grammar({
$.continue_statement,
$.goto_statement,
$.block,
$.empty_statement
$.empty_statement,
),
empty_statement: $ => ';',
empty_statement: _ => ';',
_simple_statement: $ => choice(
$._expression,
$.expression_statement,
$.send_statement,
$.inc_statement,
$.dec_statement,
$.assignment_statement,
$.short_var_declaration
$.short_var_declaration,
),
expression_statement: $ => $._expression,
send_statement: $ => seq(
field('channel', $._expression),
'<-',
field('value', $._expression)
field('value', $._expression),
),
receive_statement: $ => seq(
optional(seq(
field('left', $.expression_list),
choice('=', ':=')
choice('=', ':='),
)),
field('right', $._expression)
field('right', $._expression),
),
inc_statement: $ => seq(
$._expression,
'++'
'++',
),
dec_statement: $ => seq(
$._expression,
'--'
'--',
),
assignment_statement: $ => seq(
field('left', $.expression_list),
field('operator', choice(...assignment_operators)),
field('right', $.expression_list)
field('right', $.expression_list),
),
short_var_declaration: $ => seq(
@ -507,24 +521,24 @@ module.exports = grammar({
// conflicts between identifiers as expressions vs identifiers here.
field('left', $.expression_list),
':=',
field('right', $.expression_list)
field('right', $.expression_list),
),
labeled_statement: $ => seq(
field('label', alias($.identifier, $.label_name)),
':',
$._statement
$._statement,
),
empty_labeled_statement: $ => seq(
field('label', alias($.identifier, $.label_name)),
':'
':',
),
// This is a hack to prevent `fallthrough_statement` from being parsed as
// a single token. For consistency with `break_statement` etc it should
// be parsed as a parent node that *contains* a `fallthrough` token.
fallthrough_statement: $ => prec.left('fallthrough'),
fallthrough_statement: _ => prec.left('fallthrough'),
break_statement: $ => seq('break', optional(alias($.identifier, $.label_name))),
@ -542,20 +556,20 @@ module.exports = grammar({
'if',
optional(seq(
field('initializer', $._simple_statement),
';'
';',
)),
field('condition', $._expression),
field('consequence', $.block),
optional(seq(
'else',
field('alternative', choice($.block, $.if_statement))
))
field('alternative', choice($.block, $.if_statement)),
)),
),
for_statement: $ => seq(
'for',
optional(choice($._expression, $.for_clause, $.range_clause)),
field('body', $.block)
field('body', $.block),
),
for_clause: $ => seq(
@ -563,41 +577,41 @@ module.exports = grammar({
';',
field('condition', optional($._expression)),
';',
field('update', optional($._simple_statement))
field('update', optional($._simple_statement)),
),
range_clause: $ => seq(
optional(seq(
field('left', $.expression_list),
choice('=', ':=')
choice('=', ':='),
)),
'range',
field('right', $._expression)
field('right', $._expression),
),
expression_switch_statement: $ => seq(
'switch',
optional(seq(
field('initializer', $._simple_statement),
';'
';',
)),
field('value', optional($._expression)),
'{',
repeat(choice($.expression_case, $.default_case)),
'}'
'}',
),
expression_case: $ => seq(
'case',
field('value', $.expression_list),
':',
optional($._statement_list)
optional($._statement_list),
),
default_case: $ => seq(
'default',
':',
optional($._statement_list)
optional($._statement_list),
),
type_switch_statement: $ => seq(
@ -605,41 +619,41 @@ module.exports = grammar({
$._type_switch_header,
'{',
repeat(choice($.type_case, $.default_case)),
'}'
'}',
),
_type_switch_header: $ => seq(
optional(seq(
field('initializer', $._simple_statement),
';'
';',
)),
optional(seq(field('alias', $.expression_list), ':=')),
field('value', $._expression),
'.',
'(',
'type',
')'
')',
),
type_case: $ => seq(
'case',
field('type', commaSep1($._type)),
':',
optional($._statement_list)
optional($._statement_list),
),
select_statement: $ => seq(
'select',
'{',
repeat(choice($.communication_case, $.default_case)),
'}'
'}',
),
communication_case: $ => seq(
'case',
field('communication', choice($.send_statement, $.receive_statement)),
':',
optional($._statement_list)
optional($._statement_list),
),
_expression: $ => choice(
@ -664,30 +678,30 @@ module.exports = grammar({
$.true,
$.false,
$.iota,
$.parenthesized_expression
$.parenthesized_expression,
),
parenthesized_expression: $ => seq(
'(',
$._expression,
')'
')',
),
call_expression: $ => prec(PREC.primary, choice(
seq(
field('function', alias(choice('new', 'make'), $.identifier)),
field('arguments', alias($.special_argument_list, $.argument_list))
field('arguments', alias($.special_argument_list, $.argument_list)),
),
seq(
field('function', $._expression),
field('type_arguments', optional($.type_arguments)),
field('arguments', $.argument_list)
)
field('arguments', $.argument_list),
),
)),
variadic_argument: $ => prec.right(seq(
$._expression,
'...'
'...',
)),
special_argument_list: $ => seq(
@ -695,7 +709,7 @@ module.exports = grammar({
$._type,
repeat(seq(',', $._expression)),
optional(','),
')'
')',
),
argument_list: $ => seq(
@ -703,22 +717,22 @@ module.exports = grammar({
optional(seq(
choice($._expression, $.variadic_argument),
repeat(seq(',', choice($._expression, $.variadic_argument))),
optional(',')
optional(','),
)),
')'
')',
),
selector_expression: $ => prec(PREC.primary, seq(
field('operand', $._expression),
'.',
field('field', $._field_identifier)
field('field', $._field_identifier),
)),
index_expression: $ => prec(PREC.primary, seq(
field('operand', $._expression),
'[',
field('index', $._expression),
']'
']',
)),
slice_expression: $ => prec(PREC.primary, seq(
@ -728,17 +742,17 @@ module.exports = grammar({
seq(
field('start', optional($._expression)),
':',
field('end', optional($._expression))
field('end', optional($._expression)),
),
seq(
field('start', optional($._expression)),
':',
field('end', $._expression),
':',
field('capacity', $._expression)
)
field('capacity', $._expression),
),
),
']'
']',
)),
type_assertion_expression: $ => prec(PREC.primary, seq(
@ -746,7 +760,7 @@ module.exports = grammar({
'.',
'(',
field('type', $._type),
')'
')',
)),
type_conversion_expression: $ => prec.dynamic(-1, seq(
@ -754,7 +768,7 @@ module.exports = grammar({
'(',
field('operand', $._expression),
optional(','),
')'
')',
)),
composite_literal: $ => prec(PREC.composite_literal, seq(
@ -766,9 +780,9 @@ module.exports = grammar({
$.struct_type,
$._type_identifier,
$.generic_type,
$.qualified_type
$.qualified_type,
)),
field('body', $.literal_value)
field('body', $.literal_value),
)),
literal_value: $ => seq(
@ -777,7 +791,7 @@ module.exports = grammar({
seq(
commaSep(choice($.literal_element, $.keyed_element)),
optional(','))),
'}'
'}',
),
literal_element: $ => choice($._expression, $.literal_value),
@ -793,12 +807,12 @@ module.exports = grammar({
'func',
field('parameters', $.parameter_list),
field('result', optional(choice($.parameter_list, $._simple_type))),
field('body', $.block)
field('body', $.block),
),
unary_expression: $ => prec(PREC.unary, seq(
field('operator', choice('+', '-', '!', '^', '*', '&', '<-')),
field('operand', $._expression)
field('operand', $._expression),
)),
binary_expression: $ => {
@ -811,24 +825,23 @@ module.exports = grammar({
];
return choice(...table.map(([precedence, operator]) =>
// @ts-ignore
prec.left(precedence, seq(
field('left', $._expression),
// @ts-ignore
field('operator', operator),
field('right', $._expression)
))
field('right', $._expression),
)),
));
},
qualified_type: $ => seq(
field('package', $._package_identifier),
'.',
field('name', $._type_identifier)
field('name', $._type_identifier),
),
identifier: $ => token(seq(
letter,
repeat(choice(letter, unicodeDigit))
)),
identifier: _ => /[_\p{XID_Start}][_\p{XID_Continue}]*/,
_type_identifier: $ => alias($.identifier, $.type_identifier),
_field_identifier: $ => alias($.identifier, $.field_identifier),
@ -836,44 +849,44 @@ module.exports = grammar({
_string_literal: $ => choice(
$.raw_string_literal,
$.interpreted_string_literal
$.interpreted_string_literal,
),
raw_string_literal: $ => token(seq(
raw_string_literal: _ => token(seq(
'`',
repeat(/[^`]/),
'`'
'`',
)),
interpreted_string_literal: $ => seq(
'"',
repeat(choice(
$._interpreted_string_literal_basic_content,
$.escape_sequence
$.escape_sequence,
)),
token.immediate('"')
token.immediate('"'),
),
_interpreted_string_literal_basic_content: $ => token.immediate(prec(1, /[^"\n\\]+/)),
_interpreted_string_literal_basic_content: _ => token.immediate(prec(1, /[^"\n\\]+/)),
escape_sequence: $ => token.immediate(seq(
escape_sequence: _ => token.immediate(seq(
'\\',
choice(
/[^xuU]/,
/\d{2,3}/,
/x[0-9a-fA-F]{2,}/,
/u[0-9a-fA-F]{4}/,
/U[0-9a-fA-F]{8}/
)
/U[0-9a-fA-F]{8}/,
),
)),
int_literal: $ => token(intLiteral),
int_literal: _ => token(intLiteral),
float_literal: $ => token(floatLiteral),
float_literal: _ => token(floatLiteral),
imaginary_literal: $ => token(imaginaryLiteral),
imaginary_literal: _ => token(imaginaryLiteral),
rune_literal: $ => token(seq(
"'",
rune_literal: _ => token(seq(
'\'',
choice(
/[^'\\]/,
seq(
@ -883,34 +896,50 @@ module.exports = grammar({
seq(octalDigit, octalDigit, octalDigit),
seq('u', hexDigit, hexDigit, hexDigit, hexDigit),
seq('U', hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit),
seq(choice('a', 'b', 'f', 'n', 'r', 't', 'v', '\\', "'", '"'))
)
)
seq(choice('a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"')),
),
),
"'"
),
'\'',
)),
nil: $ => 'nil',
true: $ => 'true',
false: $ => 'false',
iota: $ => 'iota',
nil: _ => 'nil',
true: _ => 'true',
false: _ => 'false',
iota: _ => 'iota',
// http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
comment: $ => token(choice(
comment: _ => token(choice(
seq('//', /.*/),
seq(
'/*',
/[^*]*\*+([^/*][^*]*\*+)*/,
'/'
)
))
}
})
'/',
),
)),
},
});
/**
* Creates a rule to match one or more of the rules separated by a comma
*
* @param {Rule} rule
*
* @return {SeqRule}
*
*/
function commaSep1(rule) {
return seq(rule, repeat(seq(',', rule)))
return seq(rule, repeat(seq(',', rule)));
}
/**
* Creates a rule to optionally match one or more of the rules separated by a comma
*
* @param {Rule} rule
*
* @return {ChoiceRule}
*
*/
function commaSep(rule) {
return optional(commaSep1(rule))
return optional(commaSep1(rule));
}

@ -1,6 +1,6 @@
{
"name": "tree-sitter-go",
"version": "0.19.1",
"version": "0.20.0",
"description": "Go grammar for tree-sitter",
"main": "bindings/node",
"keywords": [
@ -17,10 +17,13 @@
"nan": "^2.14.0"
},
"devDependencies": {
"tree-sitter-cli": "^0.20.6"
"eslint": "^8.45.0",
"eslint-config-google": "^0.14.0",
"tree-sitter-cli": "^0.20.8"
},
"scripts": {
"build": "tree-sitter generate && node-gyp build",
"lint": "eslint grammar.js",
"test": "tree-sitter test && script/parse-examples",
"test-windows": "tree-sitter test"
},

@ -1,5 +1 @@
# Unhandled identifier character: 'ŝ'
examples/go/src/math/big/arith.go
# Unhandled identifier character: 'ƒ'
examples/moby/vendor/github.com/beorn7/perks/quantile/stream.go
examples/moby/daemon/logger/journald/read_test.go

@ -1,36 +1,47 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
set -eu
cd "$(dirname "$0")/.."
function checkout_at() {
repo=$1; url=$2; sha=$3
if [ ! -d "$repo" ]; then
git clone "https://github.com/$url" "$repo"
function clone_repo {
owner=$1
name=$2
sha=$3
path=examples/$name
if [ ! -d "$path" ]; then
echo "Cloning $owner/$name"
git clone "https://github.com/$owner/$name" "$path"
fi
pushd "$repo"
git fetch && git reset --hard "$sha"
popd
pushd "$path" >/dev/null
actual_sha=$(git rev-parse HEAD)
if [ "$actual_sha" != "$sha" ]; then
echo "Updating $owner/$name to $sha"
git fetch
git reset --hard "$sha"
fi
popd >/dev/null
}
checkout_at "examples/go" "golang/go" "870e12d7bfaea70fb0d743842f5864eb059cb939"
checkout_at "examples/moby" "moby/moby" "f57f260b49b6142366e6bc1274204ee0a1205945"
clone_repo golang go d75cc4b9c6e2acb4d0ed3d90c9a8b38094af281b
clone_repo moby moby ecbd126d6ac8c6818786f67e87f723543a037adb
known_failures="$(cat script/known-failures.txt | egrep -v '^#')"
known_failures="$(cat script/known-failures.txt)"
time tree-sitter parse -q \
# shellcheck disable=2046
tree-sitter parse -q \
'examples/**/*.go' \
'!**/testdata/**/*' \
'!**/go/test/**/*' \
$(for failure in $known_failures; do echo "!${failure}"; done)
example_count=$(find examples -name '*.go' | egrep -v 'go/test|testdata' | wc -l)
failure_count=$(wc -w <<< "$known_failures")
success_count=$(( $example_count - $failure_count ))
success_percent=$(bc -l <<< "100*${success_count}/${example_count}")
example_count=$(find examples -name '*.go' | grep -E -v -c 'go/test|testdata')
failure_count=$(wc -w <<<"$known_failures")
success_count=$((example_count - failure_count))
success_percent=$(bc -l <<<"100*${success_count}/${example_count}")
printf \
"Successfully parsed %d of %d example files (%.1f%%)\n" \
$success_count $example_count $success_percent
$success_count "$example_count" "$success_percent"

@ -3,6 +3,9 @@
"word": "identifier",
"rules": {
"source_file": {
"type": "SEQ",
"members": [
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
@ -24,6 +27,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
}
@ -36,9 +43,6 @@
"type": "SYMBOL",
"name": "_top_level_declaration"
},
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
@ -49,11 +53,10 @@
{
"type": "STRING",
"value": ";"
}
]
},
{
"type": "BLANK"
"type": "STRING",
"value": "\u0000"
}
]
}
@ -62,6 +65,20 @@
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_top_level_declaration"
},
{
"type": "BLANK"
}
]
}
]
},
"_top_level_declaration": {
"type": "CHOICE",
"members": [
@ -175,15 +192,48 @@
"type": "STRING",
"value": "("
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "import_spec"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "\n"
},
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
},
{
"type": "SYMBOL",
"name": "import_spec"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
@ -194,11 +244,24 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
@ -263,6 +326,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
}
@ -398,6 +465,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
}
@ -812,6 +883,9 @@
]
},
"parameter_declaration": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
@ -864,6 +938,7 @@
}
}
]
}
},
"variadic_parameter_declaration": {
"type": "SEQ",
@ -976,6 +1051,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
}
@ -1159,6 +1238,14 @@
{
"type": "SYMBOL",
"name": "function_type"
},
{
"type": "SYMBOL",
"name": "union_type"
},
{
"type": "SYMBOL",
"name": "negated_type"
}
]
},
@ -1178,6 +1265,14 @@
{
"type": "SYMBOL",
"name": "qualified_type"
},
{
"type": "SYMBOL",
"name": "union_type"
},
{
"type": "SYMBOL",
"name": "negated_type"
}
]
}
@ -1264,6 +1359,9 @@
}
},
"array_type": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
@ -1291,6 +1389,7 @@
}
}
]
}
},
"implicit_length_array_type": {
"type": "SEQ",
@ -1318,6 +1417,9 @@
]
},
"slice_type": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
@ -1337,6 +1439,7 @@
}
}
]
}
},
"struct_type": {
"type": "SEQ",
@ -1351,6 +1454,44 @@
}
]
},
"union_type": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_type"
},
{
"type": "STRING",
"value": "|"
},
{
"type": "SYMBOL",
"name": "_type"
}
]
}
},
"negated_type": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "~"
},
{
"type": "SYMBOL",
"name": "_type"
}
]
}
},
"field_declaration_list": {
"type": "SEQ",
"members": [
@ -1383,6 +1524,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
},
@ -1406,6 +1551,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
},
@ -1507,6 +1656,10 @@
{
"type": "SYMBOL",
"name": "qualified_type"
},
{
"type": "SYMBOL",
"name": "generic_type"
}
]
}
@ -1569,6 +1722,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
},
@ -1592,6 +1749,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
},
@ -1620,82 +1781,20 @@
"type": "SYMBOL",
"name": "method_spec"
},
{
"type": "SYMBOL",
"name": "interface_type_name"
},
{
"type": "SYMBOL",
"name": "constraint_elem"
},
{
"type": "SYMBOL",
"name": "struct_elem"
}
]
},
"interface_type_name": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_type_identifier"
},
{
"type": "SYMBOL",
"name": "qualified_type"
}
]
},
"constraint_elem": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "constraint_term"
},
{
"type": "REPEAT",
"type": "ALIAS",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "SYMBOL",
"name": "constraint_term"
}
]
}
}
]
},
"constraint_term": {
"type": "PREC",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "~"
},
{
"type": "BLANK"
}
]
"name": "_simple_type"
},
{
"type": "SYMBOL",
"name": "_type_identifier"
"named": true,
"value": "constraint_elem"
}
]
}
},
"struct_elem": {
"type": "SEQ",
@ -1724,7 +1823,7 @@
},
"struct_term": {
"type": "PREC",
"value": -1,
"value": 1,
"content": {
"type": "SEQ",
"members": [
@ -1803,6 +1902,9 @@
]
},
"map_type": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
@ -1834,8 +1936,12 @@
}
}
]
}
},
"channel_type": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
{
@ -1902,8 +2008,12 @@
}
}
]
}
},
"function_type": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
@ -1944,6 +2054,7 @@
}
}
]
}
},
"block": {
"type": "SEQ",
@ -1995,6 +2106,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
},
@ -2021,6 +2136,10 @@
{
"type": "STRING",
"value": ";"
},
{
"type": "STRING",
"value": "\u0000"
}
]
},
@ -2143,7 +2262,7 @@
"members": [
{
"type": "SYMBOL",
"name": "_expression"
"name": "expression_statement"
},
{
"type": "SYMBOL",
@ -2167,6 +2286,10 @@
}
]
},
"expression_statement": {
"type": "SYMBOL",
"name": "_expression"
},
"send_statement": {
"type": "SEQ",
"members": [
@ -4312,50 +4435,8 @@
]
},
"identifier": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "\\p{L}"
},
{
"type": "STRING",
"value": "_"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "\\p{L}"
},
{
"type": "STRING",
"value": "_"
}
]
},
{
"type": "PATTERN",
"value": "[0-9]"
}
]
}
}
]
}
"value": "[_\\p{XID_Start}][_\\p{XID_Continue}]*"
},
"_type_identifier": {
"type": "ALIAS",
@ -6789,10 +6870,6 @@
"generic_type",
"_simple_type"
],
[
"parameter_declaration",
"type_arguments"
],
[
"parameter_declaration",
"_simple_type",
@ -6807,13 +6884,6 @@
"parameter_declaration",
"_expression"
],
[
"func_literal",
"function_type"
],
[
"function_type"
],
[
"parameter_declaration",
"_simple_type"

@ -98,15 +98,15 @@
"named": true,
"subtypes": [
{
"type": "_expression",
"type": "assignment_statement",
"named": true
},
{
"type": "assignment_statement",
"type": "dec_statement",
"named": true
},
{
"type": "dec_statement",
"type": "expression_statement",
"named": true
},
{
@ -151,6 +151,10 @@
"type": "map_type",
"named": true
},
{
"type": "negated_type",
"named": true
},
{
"type": "pointer_type",
"named": true
@ -170,6 +174,10 @@
{
"type": "type_identifier",
"named": true
},
{
"type": "union_type",
"named": true
}
]
},
@ -727,36 +735,6 @@
}
}
},
{
"type": "constraint_elem",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "constraint_term",
"named": true
}
]
}
},
{
"type": "constraint_term",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "type_identifier",
"named": true
}
]
}
},
{
"type": "continue_statement",
"named": true,
@ -868,6 +846,21 @@
]
}
},
{
"type": "expression_statement",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "_expression",
"named": true
}
]
}
},
{
"type": "expression_switch_statement",
"named": true,
@ -949,6 +942,10 @@
"type": "_type",
"named": true
},
{
"type": "generic_type",
"named": true
},
{
"type": "qualified_type",
"named": true
@ -1184,6 +1181,10 @@
"multiple": false,
"required": true,
"types": [
{
"type": "negated_type",
"named": true
},
{
"type": "qualified_type",
"named": true
@ -1191,6 +1192,10 @@
{
"type": "type_identifier",
"named": true
},
{
"type": "union_type",
"named": true
}
]
},
@ -1427,10 +1432,6 @@
"type": "constraint_elem",
"named": true
},
{
"type": "interface_type_name",
"named": true
},
{
"type": "method_spec",
"named": true
@ -1442,25 +1443,6 @@
]
}
},
{
"type": "interface_type_name",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "qualified_type",
"named": true
},
{
"type": "type_identifier",
"named": true
}
]
}
},
{
"type": "interpreted_string_literal",
"named": true,
@ -1681,6 +1663,21 @@
}
}
},
{
"type": "negated_type",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "_type",
"named": true
}
]
}
},
{
"type": "package_clause",
"named": true,
@ -2407,6 +2404,21 @@
}
}
},
{
"type": "union_type",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "_type",
"named": true
}
]
}
},
{
"type": "var_declaration",
"named": true,
@ -2503,6 +2515,10 @@
}
}
},
{
"type": "\u0000",
"named": false
},
{
"type": "\n",
"named": false

Binary file not shown.

@ -248,6 +248,7 @@ func g1[T, U any, V interface{}, W Foo[Bar[T]]](a Foo[T]) {}
func g1[T, U any, V interface{}, W Foo[Bar[T]]](a Foo[T]) {}
func g2(a foo.bar[int]) {}
func f[A int|string, B ~int, C ~int|~string]()
func f2(a File, b, c, d Thing) int {}
--------------------------------------------------------------------------------
@ -371,19 +372,34 @@ func f[A int|string, B ~int, C ~int|~string]()
(type_parameter_list
(parameter_declaration
(identifier)
(ERROR
(identifier))
(union_type
(type_identifier)
(type_identifier)))
(parameter_declaration
(identifier)
(negated_type
(type_identifier)))
(parameter_declaration
(identifier)
(union_type
(negated_type
(type_identifier))
(negated_type
(type_identifier)))))
(parameter_list))
(function_declaration
(identifier)
(parameter_list
(parameter_declaration
(identifier)
(ERROR)
(type_identifier))
(parameter_declaration
(identifier)
(ERROR
(identifier))
(identifier)
(identifier)
(type_identifier)))
(parameter_list)))
(type_identifier)
(block)))
================================================================================
Single-line function declarations
@ -404,29 +420,34 @@ func f3() { a(); b(); }
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(identifier)
(argument_list))))
(argument_list)))))
(function_declaration
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(identifier)
(argument_list))
(argument_list)))
(expression_statement
(call_expression
(identifier)
(argument_list))))
(argument_list)))))
(function_declaration
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(identifier)
(argument_list))
(argument_list)))
(expression_statement
(call_expression
(identifier)
(argument_list)))))
(argument_list))))))
================================================================================
Variadic function declarations

@ -0,0 +1,452 @@
================================================================================
Call expressions
================================================================================
package main
func main() {
a(b, c...)
a(
b,
c,
)
a(
b,
c...,
)
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(identifier)
(argument_list
(identifier)
(variadic_argument
(identifier)))))
(expression_statement
(call_expression
(identifier)
(argument_list
(identifier)
(identifier))))
(expression_statement
(call_expression
(identifier)
(argument_list
(identifier)
(variadic_argument
(identifier))))))))
================================================================================
Nested call expressions
================================================================================
package main
func main() {
a(b(c(d)))
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(identifier)
(argument_list
(call_expression
(identifier)
(argument_list
(call_expression
(identifier)
(argument_list
(identifier)))))))))))
================================================================================
Generic call expressions
================================================================================
package main
func main() {
a[b](c)
a[b, c](d)
a[b[c], d](e[f])
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(identifier)
(type_arguments
(type_identifier))
(argument_list
(identifier))))
(expression_statement
(call_expression
(identifier)
(type_arguments
(type_identifier)
(type_identifier))
(argument_list
(identifier))))
(expression_statement
(call_expression
(identifier)
(type_arguments
(generic_type
(type_identifier)
(type_arguments
(type_identifier)))
(type_identifier))
(argument_list
(index_expression
(identifier)
(identifier))))))))
================================================================================
Calls to 'make' and 'new'
================================================================================
package main
func main() {
make(chan<- int)
// `new` and `make` can also be used as variable names
make(chan<- int, (new - old), make.stuff)
make(chan<- int, 5, 10)
new(map[string]string)
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(identifier)
(argument_list
(channel_type
(type_identifier)))))
(comment)
(expression_statement
(call_expression
(identifier)
(argument_list
(channel_type
(type_identifier))
(parenthesized_expression
(binary_expression
(identifier)
(identifier)))
(selector_expression
(identifier)
(field_identifier)))))
(expression_statement
(call_expression
(identifier)
(argument_list
(channel_type
(type_identifier))
(int_literal)
(int_literal))))
(expression_statement
(call_expression
(identifier)
(argument_list
(map_type
(type_identifier)
(type_identifier))))))))
================================================================================
Selector expressions
================================================================================
package main
func main() {
a.b.c()
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(selector_expression
(selector_expression
(identifier)
(field_identifier))
(field_identifier))
(argument_list))))))
================================================================================
Indexing expressions
================================================================================
package main
func main() {
_ = a[1]
_ = b[:]
_ = c[1:]
_ = d[1:2]
_ = e[:2:3]
_ = f[1:2:3]
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(assignment_statement
(expression_list
(identifier))
(expression_list
(index_expression
(identifier)
(int_literal))))
(assignment_statement
(expression_list
(identifier))
(expression_list
(slice_expression
(identifier))))
(assignment_statement
(expression_list
(identifier))
(expression_list
(slice_expression
(identifier)
(int_literal))))
(assignment_statement
(expression_list
(identifier))
(expression_list
(slice_expression
(identifier)
(int_literal)
(int_literal))))
(assignment_statement
(expression_list
(identifier))
(expression_list
(slice_expression
(identifier)
(int_literal)
(int_literal))))
(assignment_statement
(expression_list
(identifier))
(expression_list
(slice_expression
(identifier)
(int_literal)
(int_literal)
(int_literal)))))))
================================================================================
Type assertion expressions
================================================================================
package main
func main() {
_ = a.(p.Person)
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(assignment_statement
(expression_list
(identifier))
(expression_list
(type_assertion_expression
(identifier)
(qualified_type
(package_identifier)
(type_identifier))))))))
================================================================================
Type conversion expressions
================================================================================
package main
func main() {
_ = []a.b(c.d)
_ = ([]a.b)(c.d)
_ = <-chan int(c) // conversion to channel type
<-(chan int(c)) // receive statement
// These type conversions cannot be distinguished from call expressions
T(x)
(*Point)(p)
e.f(g)
(e.f)(g)
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(assignment_statement
(expression_list
(identifier))
(expression_list
(type_conversion_expression
(slice_type
(qualified_type
(package_identifier)
(type_identifier)))
(selector_expression
(identifier)
(field_identifier)))))
(assignment_statement
(expression_list
(identifier))
(expression_list
(type_conversion_expression
(parenthesized_type
(slice_type
(qualified_type
(package_identifier)
(type_identifier))))
(selector_expression
(identifier)
(field_identifier)))))
(assignment_statement
(expression_list
(identifier))
(expression_list
(type_conversion_expression
(channel_type
(type_identifier))
(identifier))))
(comment)
(expression_statement
(unary_expression
(parenthesized_expression
(type_conversion_expression
(channel_type
(type_identifier))
(identifier)))))
(comment)
(comment)
(expression_statement
(call_expression
(identifier)
(argument_list
(identifier))))
(expression_statement
(call_expression
(parenthesized_expression
(unary_expression
(identifier)))
(argument_list
(identifier))))
(expression_statement
(call_expression
(selector_expression
(identifier)
(field_identifier))
(argument_list
(identifier))))
(expression_statement
(call_expression
(parenthesized_expression
(selector_expression
(identifier)
(field_identifier)))
(argument_list
(identifier)))))))
================================================================================
Unary expressions
================================================================================
package main
func main() {
_ = !<-a
_ = *foo()
}
--------------------------------------------------------------------------------
(source_file
(package_clause
(package_identifier))
(function_declaration
(identifier)
(parameter_list)
(block
(assignment_statement
(expression_list
(identifier))
(expression_list
(unary_expression
(unary_expression
(identifier)))))
(assignment_statement
(expression_list
(identifier))
(expression_list
(unary_expression
(call_expression
(identifier)
(argument_list))))))))

@ -35,6 +35,8 @@ Grouped import declarations
package a
import()
import ("fmt")
import (
"net/http"
. "some/dsl"
@ -46,6 +48,9 @@ import (
(source_file
(package_clause (package_identifier))
(import_declaration (import_spec_list))
(import_declaration (import_spec_list
(import_spec (interpreted_string_literal))))
(import_declaration (import_spec_list
(import_spec (interpreted_string_literal))
(import_spec (dot) (interpreted_string_literal))

@ -48,10 +48,11 @@ func main() {
(identifier)
(parameter_list)
(block
(expression_statement
(call_expression
(identifier)
(argument_list
(int_literal))))))
(int_literal)))))))
================================================================================
Send statements
@ -269,9 +270,10 @@ func main() {
(if_statement
condition: (identifier)
consequence: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list))))
arguments: (argument_list)))))
(if_statement
initializer: (short_var_declaration
left: (expression_list
@ -282,35 +284,41 @@ func main() {
arguments: (argument_list))))
condition: (identifier)
consequence: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list))))
arguments: (argument_list)))))
(if_statement
condition: (identifier)
consequence: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list)))
arguments: (argument_list))))
alternative: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list))))
arguments: (argument_list)))))
(if_statement
condition: (identifier)
consequence: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list)))
arguments: (argument_list))))
alternative: (if_statement
condition: (identifier)
consequence: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list)))
arguments: (argument_list))))
alternative: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list))))))))
arguments: (argument_list)))))))))
================================================================================
For statements
@ -357,9 +365,10 @@ loop2:
(block
(for_statement
(block
(expression_statement
(call_expression
(identifier)
(argument_list))
(argument_list)))
(goto_statement
(label_name))))
(labeled_statement
@ -377,9 +386,10 @@ loop2:
(inc_statement
(identifier)))
(block
(expression_statement
(call_expression
(identifier)
(argument_list))
(argument_list)))
(break_statement
(label_name)))))
(labeled_statement
@ -392,17 +402,19 @@ loop2:
(inc_statement
(identifier)))
(block
(expression_statement
(call_expression
(identifier)
(argument_list))
(argument_list)))
(continue_statement
(label_name)))))
(for_statement
(for_clause)
(block
(expression_statement
(call_expression
(identifier)
(argument_list))
(argument_list)))
(continue_statement)))
(for_statement
(range_clause
@ -410,10 +422,11 @@ loop2:
(identifier))
(identifier))
(block
(expression_statement
(call_expression
(identifier)
(argument_list
(identifier)))
(identifier))))
(break_statement))))))
================================================================================
@ -454,20 +467,23 @@ func main() {
value: (expression_list
(int_literal)
(int_literal))
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list))
arguments: (argument_list)))
(fallthrough_statement))
(expression_case
value: (expression_list
(int_literal))
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list)))
arguments: (argument_list))))
(default_case
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list))
arguments: (argument_list)))
(break_statement)))
(expression_switch_statement
(expression_case
@ -523,9 +539,10 @@ func main() {
(type_case
type: (slice_type
element: (type_identifier))
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list)))
arguments: (argument_list))))
(type_case
type: (pointer_type
(type_identifier))
@ -536,44 +553,50 @@ func main() {
value: (identifier)
(type_case
type: (type_identifier)
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(interpreted_string_literal))))
(interpreted_string_literal)))))
(type_case
type: (type_identifier)
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(identifier))))
(identifier)))))
(type_case
type: (type_identifier)
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(identifier))))
(identifier)))))
(type_case
type: (function_type
parameters: (parameter_list
(parameter_declaration
type: (type_identifier)))
result: (type_identifier))
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(identifier))))
(identifier)))))
(type_case
type: (type_identifier)
type: (type_identifier)
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(interpreted_string_literal))))
(interpreted_string_literal)))))
(default_case
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(interpreted_string_literal))))))))
(interpreted_string_literal)))))))))
================================================================================
Select statements
@ -610,18 +633,20 @@ func main() {
(identifier))
right: (unary_expression
operand: (identifier)))
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(identifier))))
(identifier)))))
(communication_case
communication: (send_statement
channel: (identifier)
value: (identifier))
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(int_literal))))
(int_literal)))))
(communication_case
communication: (receive_statement
right: (unary_expression
@ -631,10 +656,11 @@ func main() {
field: (field_identifier))
arguments: (argument_list
(int_literal)))))
(expression_statement
(call_expression
function: (identifier)
arguments: (argument_list
(int_literal))))
(int_literal)))))
(default_case
(return_statement))))))
@ -692,15 +718,17 @@ func main() {
(parameter_list)
(block
(block
(expression_statement
(call_expression
(identifier)
(argument_list
(interpreted_string_literal))))
(interpreted_string_literal)))))
(block
(expression_statement
(call_expression
(identifier)
(argument_list
(interpreted_string_literal)))))))
(interpreted_string_literal))))))))
================================================================================
Labels at the ends of statement blocks
@ -776,6 +804,7 @@ func main() {
(identifier))
(identifier))
(block
(expression_statement
(call_expression
(func_literal
(parameter_list)
@ -785,6 +814,7 @@ func main() {
(identifier)
(identifier))
(block
(expression_statement
(call_expression
(selector_expression
(identifier)
@ -793,8 +823,8 @@ func main() {
(interpreted_string_literal)
(index_expression
(identifier)
(identifier))))))))
(argument_list)))))))
(identifier)))))))))
(argument_list))))))))
================================================================================
Top-level statements
@ -806,10 +836,11 @@ x := T { a: b }
--------------------------------------------------------------------------------
(source_file
(expression_statement
(call_expression
(identifier)
(argument_list
(int_literal)))
(int_literal))))
(short_var_declaration
(expression_list
(identifier))

@ -205,7 +205,7 @@ type SignedInteger interface {
(type_spec
(type_identifier)
(interface_type
(interface_type_name
(constraint_elem
(qualified_type
(package_identifier)
(type_identifier))))))
@ -213,9 +213,9 @@ type SignedInteger interface {
(type_spec
(type_identifier)
(interface_type
(interface_type_name
(constraint_elem
(type_identifier))
(interface_type_name
(constraint_elem
(qualified_type
(package_identifier)
(type_identifier)))
@ -239,14 +239,15 @@ type SignedInteger interface {
(type_identifier)
(interface_type
(constraint_elem
(constraint_term
(type_identifier))
(constraint_term
(type_identifier))
(constraint_term
(union_type
(union_type
(union_type
(type_identifier)
(type_identifier))
(constraint_term
(type_identifier)))))))
(negated_type
(type_identifier)))
(negated_type
(type_identifier))))))))
================================================================================
Interface embedded struct types