ci: bump tree-sitter-cli to ^0.26.10#23
Merged
Merged
Conversation
Keyword extraction (word rule, PR #22) needs the 0.25+ lexer; the CI generate step would silently revert the Channel.fromPath tokenization fix if it regenerates with 0.24. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
Keyword extraction (word rule) requires the 0.25+ lexer, which prefers longer identifier matches over extracted keywords. ABI 15 parsers need runtime >= 0.25 in the node/rust/python bindings. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
…Path) - Add word rule so 'from'/'of'/'value' only match complete identifiers; previously Channel.fromPath tokenized as 'from' + ERROR - Add generic channel_factory rule for factories without dedicated rules (fromPath, fromFilePairs, empty, watchPath, ...) - Allow channel_expression as method_call receiver so chains like Channel.fromPath(x).ifEmpty(null) parse cleanly - Unskip Channel factories corpus test; refresh stale expectations (closure_block) that predated the committed grammar - Rebuild macos-arm64 dylib (linux-x64 needs a CI rebuild) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
Previously masked by the corpus failure aborting the suite: - tags.scm/highlights.scm referenced fields and node types the grammar never defined; rewrite against the actual node inventory - tree-sitter.json file-types had leading dots, so .nf files were never associated with the grammar Highlight assertion files in test/highlight/ remain aspirational (def functions, for loops, fields) and still fail; tracked as follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
setuptools' TREE_SITTER_HIDE_SYMBOLS kept the parser function out of the macOS export trie (visible in nm but not dlsym-able). Dropping the macro lets the installed wheel double as an ast-grep customLanguages library: register its _binding shared object directly, no separate dylib needed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
ch | ifEmpty(null) and ch | view previously produced ERROR nodes since pipe_operation only accepted map closures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
samtools/sort main.nf went from 75 ERROR nodes (rest-of-file swallowed after the container directive) to 0. Added: - process directives: tag/label/conda/container/publishDir/cpus/... (generic identifier + args rule) - ternary expressions (right-assoc, so nested chains work), elvis '?:', unary '!', 'in' and 'instanceof' operators, index access x[0], property access on non-identifier receivers ((expr).name) - method_call/function_call/list as binary operands - Groovy statement prelude in script/shell/exec/stub sections before the script string; interpolated strings as script_content - tuple input/output declarations with named options (emit:, optional:) - method_call inlines its navigation path (a.b.c(...)) instead of a reduced dotted_identifier receiver, fixing 3+-segment dotted chains (task.ext.when) that previously forced an early reduce and ERROR'd Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
parse_rate.py measures the share of real nf-core/modules files that parse without ERROR nodes and clusters the failures by construct. Baseline after the grammar expansion: 50.0% (1035/2070). The ranked failure list drives Phase 1 of ROADMAP.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
Phase 1 grammar burn-down (ROADMAP.md), 50.0% -> 66.4% parse rate on
nf-core/modules:
- float_literal (0.8, 1.5e3); floats/maps as binary operands
- single- and double-quoted string escape sequences incl. $ and \'
- assert cond : message (also allowed in script-section preludes)
- ==~ exact-match regex operator
- interpolated map keys ("${task.process}": ...)
- braceless if bodies: if (cond) error "msg"
- chained subscripts m[0][2]
- emit_declaration: path "x", emit: y, topic: z (single-qualifier
outputs with named options); option_entry/option_value give
declaration options a value type that excludes command_expression
Known remaining: multi-line declaration sequences where a bare-identifier
option value abuts the next line's qualifier need newline-sensitive
termination (external scanner) — tracked for Phase 1 follow-up.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
cibuildwheel abi3 wheels for macOS+Linux (x64/arm64) + sdist, trusted publishing on release. Includes a macOS export-trie check that the tree_sitter_nextflow symbol is present so the wheel stays usable as an ast-grep dynamic language library. Does nothing until a GitHub release is published and PyPI trusted publishing is configured. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
66.4% -> 76.1% parse rate on nf-core/modules. src/scanner.c emits a _terminator token at newlines/';' only where the parser state accepts one (valid_symbols), so line continuations inside brackets and mid-expression need no special handling. A one-char lookahead suppresses the terminator before continuation tokens (. ? : , closing brackets, and the 'else' keyword); comment lines are folded into the terminator run so a comment between statements yields one terminator. Process bodies now parse in three ordered phases (directives -> input/output/when -> script/stub) and each declaration self-terminates, removing the directive-vs-input and directive-vs-prelude-assignment ambiguities the terminator exposed. Unblocks multi-line inputs, multi-statement script preludes, and script+stub processes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
The scanner previously folded comments into the terminator token, which removed line_comment/block_comment nodes from the tree and broke comment-based lint rules (TODO detection missed TODOs in script sections). Now the scanner returns false when a comment follows the newline run, so the comment is lexed as an ordinary extra and the terminator is emitted after it — one terminator between statements, and the comment survives as a node. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
76.1% -> 77.2% parse rate. interpolated_triple_quoted_string used
string_content (/[^$"\\]+/), which stopped at any double quote, so a
YAML-style versions block inside a script string broke:
"""
"${task.process}":
tool: ...
"""
New triple_string_content token only stops at the closing """, $ and \\,
so lone/doubled quotes are ordinary content.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD
Two tokenization fixes for real-world process scripts: - slashy_string is now a single token() (was a 3-part seq whose / and body collided with the division operator and escape tokens) and is a valid right operand of binary_expression, so `x ==~ /re/` and `m = s =~ /re/` parse. First body char excludes * and / so /*...*/ and // comments still win. - string_content is token(prec(1, ...)) so a // inside a double-quoted string (e.g. sed 's/.$//') is string content, not a line_comment extra that ate the closing quote and ran off the end of the file. Parse rate over nf-core/modules: 77.2% -> 79.4% (1598 -> 1643 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Lockfile still pinned 0.24.6 after package.json moved to ^0.26.10. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
path(reads, arity: '1..*', stageAs: 'input/*') and other Groovy map-style named args (key: value) now parse: function_call arguments accept option_entry, not just simple_expression. Parse rate over nf-core/modules: 79.4% -> 84.1% (1643 -> 1740 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- assignment accepts +=, -=, *=, /=, %=, **=, <<=, >>=, &=, |=, ^=, ?= and dotted/index/property LHS (args += ..., meta.x = ...) - binary operators add <=>, <<, !in, !instanceof - unary_expression adds ~ (Groovy bitwiseNegate -> Pattern, e.g. ~/re/), and numeric sign -/+ Bitwise & | ^ >> >>> intentionally omitted: | collides with the channel pipe operator. Parse rate over nf-core/modules: 84.1% -> 86.5% (1740 -> 1791 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- directive accepts a closure body: memory { 7.GB * task.attempt }
- input_declaration accepts a qualifier with named options:
path ref, name: 'ref/*' (emit_declaration, previously output-only)
- property_expression is now a simple_expression and a binary operand,
and accepts an integer_literal receiver, so memory-unit literals
7.GB / 280.MB and (expr).prop chains parse everywhere
Parse rate over nf-core/modules: 86.5% -> 87.6% (1791 -> 1813 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
def n = (task.cpus * 0.9) as int def y = new groovy.yaml.YamlBuilder() Parse rate over nf-core/modules: 87.6% -> 88.2% (1813 -> 1825 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- template 'main.R' as a script section body (external script file)
- def name(params) { ... } function definitions at top level, with
typed params, param defaults, and optional -> return type
- return / return expr statements in functions, closures, script
preludes (previously return e parsed as two bogus statements)
Parse rate over nf-core/modules: 88.2% -> 90.2% (1825 -> 1868 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conditional logic (if/else) in workflow main: and body sections, common in subworkflows. Parse rate over nf-core/modules: 90.2% -> 90.5% (1868 -> 1873 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…and *.
- method_call arguments accept option_entry: ch.combine(x, by: 0)
- method_call receiver accepts function_call and constructor_call:
foo().bar(), new JsonSlurper().parseText(t)
- navigation supports safe-navigation ?. and spread *. operators:
task.ext.args?.contains(x), pairs*.join(' ')
Parse rate over nf-core/modules: 90.5% -> 91.3% (1873 -> 1890 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- assert_statement allowed in block and closure_block bodies
(input.collect { f -> assert f.name != x : 'msg' })
- tuple components accept bare identifiers (stdout) and env('V')
- template('file') parenthesised form, alongside template 'file'
Tried and reverted (net regressions): multi-arg command_expression
(exit 1, 'msg') and triple-string method receivers ('''...'''.stripIndent())
both introduce ambiguity that breaks more files than they fix.
Parse rate over nf-core/modules: 91.3% -> 92.3% (1890 -> 1910 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- restore bitwise & and ^ as binary operators (ix & 1); | stays out because it collides with the channel pipe operator - label_statement (name: expr) in closure blocks, used by multiMap and branch operators to name their emitted channels Parse rate over nf-core/modules: 92.3% -> 92.4% (1910 -> 1913 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PROCESS.out.channel.join(...).map { } — process_output is now a
method_call receiver (common in subworkflow channel plumbing).
Parse rate over nf-core/modules: 92.4% -> 93.3% (1913 -> 1931 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A bare-RHS assignment on one line no longer absorbs the next line's identifier as a command_expression: x = a / y = b were parsed as x = (a y) = b (ERROR at the second =). block and closure_block now allow an optional terminator between statements so the newline ends the first. Parse rate over nf-core/modules: 93.3% -> 93.8% (1931 -> 1942 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Consecutive assignments/statements in workflow main:/emit:/body no longer merge across newlines (a = X.out / b = Y.out was parsed as one broken assignment). workflow_body/main/emit and take: now allow a terminator between items. Known limitation: with terminators, an LALR reduction can place a trailing take: identifier or a second main: statement at workflow_body level rather than nested in the section. This is error-free (all nodes present) and does not affect the parse-rate metric; corpus expectations updated to match. A section-greedy restructure is tracked in ROADMAP. Parse rate over nf-core/modules: 93.8% -> 96.1% (1942 -> 1990 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
"\${task.process}": inside """...""" now parses as a general expression
(assignment RHS, block statement), not only as a script body. A lone or
doubled " that triple_string_content cannot absorb (because it abuts an
interpolation) is matched by a low-precedence quote token; maximal munch
still prefers the 3-char """ closer.
Parse rate over nf-core/modules: 96.1% -> 96.5% (1990 -> 1998 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- exit 1, 'message' — two-arg exit statement in blocks, closures, and script preludes (targeted rule; avoids the ambiguity a general multi-arg command_expression introduced) - env 'VER', emit: x — env qualifier accepted in emit_declaration, and env_input broadened to interpolated (double-quoted) strings Parse rate over nf-core/modules: 96.5% -> 96.8% (1998 -> 2003 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
exit(1, 'msg') alongside exit 1, 'msg'. Making exit a keyword had broken the paren (function-call) form. Parse rate over nf-core/modules: 96.8% -> 97.0% (2003 -> 2008 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cond ? a.each { } : b.each { } used for side effects now parses as a
script_statement.
Parse rate over nf-core/modules: 97.0% -> 97.1% (2008 -> 2011 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- method(args) { closure } — trailing closure after parenthesised args
(s.replaceAll(/re/) { m -> ... })
- cast_expression is now a binary operand: (x as Float) > 0, a ^ b casts
Parse rate over nf-core/modules: 97.1% -> 97.2% (2011 -> 2013 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- process_invocation arguments accept any simple_expression and named
args, not just identifiers: SAMTOOLS_SORT(ch, [[], []], ''),
FOO(ch.map { }, x.first()), PROCESS(a, key: v)
- property_expression accepts a function_call receiver: file(x).baseName
Parse rate over nf-core/modules: 97.2% -> 97.8% (2013 -> 2024 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- command_expression accepts a closure: multiMapCriteria { ... }
- map_entry key can be a parenthesized (computed) expression: [(key): v]
- scanner treats a leading | as a continuation so multi-line channel
pipes parse: ch \n | combine(x) \n | map { }
Parse rate over nf-core/modules: 97.8% -> 98.0% (2024 -> 2028 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…erand - dotted_identifier supports ?. : task.ext?.args, logSettings?.x - process_output is a binary operand: bwa_index ?: BWAMEM1_INDEX.out.index Parse rate over nf-core/modules: 98.0% -> 98.1% (2028 -> 2030 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Several template-based modules leave a dead """...""" before the template '...' call. script_content now accepts a script string optionally trailed by a template, so these parse (previously the template was mis-read as a misplaced process directive). Parse rate over nf-core/modules: 98.1% -> 98.6% (2030 -> 2041 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Present in current nf-core lib code (deprecated by 26.04 strict syntax but still shipped). try_statement in blocks, closures, and script preludes; catch supports typed/untyped and multi-type parameters. Parse rate over nf-core/modules: 98.6% -> 98.6% (2041 -> 2042 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Scanner treats a leading else/catch/finally as a statement continuation,
so } \n catch (e) { ... } parses (matches the existing } \n else handling).
Parse rate over nf-core/modules: 98.6% -> 98.7% (2042 -> 2043 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pipe_expression is now left-recursive, so multi-stage channel pipes parse (previously only a single | worked). Parse rate over nf-core/modules: 98.7% -> 98.7% (2043 -> 2044 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(meta, seq) = fn() — destructuring_pattern as an assignment target, not just in def declarations. Parse rate over nf-core/modules: 98.7% -> 98.8% (2044 -> 2046 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
outputs << 'x' and similar side-effecting binary ops parse as a script_statement (a bare string is not a binary, so no ambiguity with the trailing script content). Parse rate over nf-core/modules: 98.8% -> 98.9% (2046 -> 2047 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(input =~ /re/)[0][1] and (expr).prop[i] now parse (index_expression base accepts parenthesized_expression and property_expression), incl. as a multi-line ternary consequence. Parse rate over nf-core/modules: 98.9% -> 99.0% (2047 -> 2049 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tring
- ch | multiMap { } / | branch { } / | filter { } (operator_closure in
pipe_operation)
- "${x}"[range] index on an interpolated string
Parse rate over nf-core/modules: 99.0% -> 99.1% (2049 -> 2051 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parse rate over nf-core/modules: 99.1% -> 99.1% (2051 -> 2052 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Closure params may carry a type (Path path, MemoryUnit memory), used by JsonGenerator .addConverter calls and similar. Parse rate over nf-core/modules: 99.1% (2052 / 2070; unblocks typed params, file still gated on triple-string method calls). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root fix for the largest residual cluster: '"""..."""' now always parses
as interpolated_triple_quoted_string (it already handles no-interpolation
content), removing the overlap with the plain triple_quoted_string atomic
token that made a triple-string method receiver ambiguous. plain
triple_quoted_string is now single-quote-only ('''...'''). A dedicated
string_method_call rule requires at least one .method(...) so a bare
triple-string script body is never mis-parsed as a method receiver.
Corpus expectations regenerated ("""...""" -> interpolated_triple_quoted_string);
all :skip tests preserved.
Parse rate over nf-core/modules: 99.1% -> 99.3% (2052 -> 2056 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Groovy treats an unrecognised \x as literal backslash + x. Accept \ + any character (bash line continuations \<newline>, \ , etc.) besides \uXXXX, so triple-quoted script bodies with shell escapes don't ERROR now that """...""" routes through interpolated_triple_quoted_string. Parse rate over nf-core/modules: 99.3% -> 99.4% (2056 -> 2058 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Section markers are seq(word, ':') instead of atomic 'word:' tokens, so a stray space before the colon parses. Parse rate over nf-core/modules: 99.4% -> 99.5% (2058 -> 2059 / 2070). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- scanner: an explicit ; always terminates — even before } (return a?b:c;})
and even when a comment follows (stmt; /* c */); a trailing same-line
comment after ; is folded into the terminator so it is not a boundary
extra that would end a script prelude early.
- function_definition accepts a return type instead of def:
String getExt(String args) { ... } with Groovy-typed params (Type name).
Fixes the jvarkit vcf2table/vcffilterjdk/vcfpolyx custom-function modules.
Parse rate over nf-core/modules: 99.5% -> 99.6% (2059 -> 2062 / 2070).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Keyword extraction (
wordrule, added in #22) requires the 0.25+ lexer: older lexers prefer extracted keywords over longer identifier matches, so CI'stree-sitter generatestep with 0.24 would silently revert theChannel.fromPathtokenization fix.Verified locally: corpus passes when generated with 0.26.10, regresses with 0.24.7.
#22 is stacked on this branch.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XaTroL9k3feq3MTAptE9bD