From feee02d2667612c60febd52ab07adfd6c7a75264 Mon Sep 17 00:00:00 2001 From: Mark Tareshawty Date: Mon, 24 Aug 2026 01:59:16 -0400 Subject: [PATCH 1/3] test: lock in behaviour for previously reported parse bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several reported parse bugs already produce the right tree but have no corpus coverage, so nothing stops them regressing. - Binary operator method names. `def !=(other)` used to produce an ERROR while `def ==(other)` parsed; cover `!=`, `==` and `<=>` alongside the existing unary operator method name test. - `...` at the start of an expression. It opens a beginless range, and must not be mistaken for argument forwarding when it appears as the first thing in a method body. - Un-terminated heredoc identifier. `<<~"BASH` with no closing quote used to abort the scanner; it now yields a bare `heredoc_beginning`. - Dot call syntax. `x.(123)` is a call, and `x.(123)(456)` — which Ruby rejects — must stay an error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- test/corpus/declarations.txt | 44 ++++++++++++++++++++++++++++++ test/corpus/expressions.txt | 53 ++++++++++++++++++++++++++++++++++++ test/corpus/literals.txt | 16 +++++++++++ 3 files changed, 113 insertions(+) diff --git a/test/corpus/declarations.txt b/test/corpus/declarations.txt index 5e1f6bd5..32c82635 100644 --- a/test/corpus/declarations.txt +++ b/test/corpus/declarations.txt @@ -1123,6 +1123,50 @@ lambda parameters with block-locals locals: (identifier)) body: (block))) +============================ +binary operator method names +============================ + +def !=(other) + self.n != other.n +end + +def ==(other) + true +end + +def <=>(other) + 0 +end + +--- + +(program + (method + name: (operator) + parameters: (method_parameters + (identifier)) + body: (body_statement + (binary + left: (call + receiver: (self) + method: (identifier)) + right: (call + receiver: (identifier) + method: (identifier))))) + (method + name: (operator) + parameters: (method_parameters + (identifier)) + body: (body_statement + (true))) + (method + name: (operator) + parameters: (method_parameters + (identifier)) + body: (body_statement + (integer)))) + =========================== unary operator method names =========================== diff --git a/test/corpus/expressions.txt b/test/corpus/expressions.txt index 87b9fdec..992925f6 100644 --- a/test/corpus/expressions.txt +++ b/test/corpus/expressions.txt @@ -613,6 +613,59 @@ a...b (identifier) (identifier))) +================================= +dot call syntax +================================= + +x.(123) +x.() + +--- + +(program + (call + receiver: (identifier) + arguments: (argument_list + (integer))) + (call + receiver: (identifier) + arguments: (argument_list))) + +=================================================== +dot call syntax rejects a second argument list +:error +=================================================== + +x.(123)(456) + +--- + +================================================== +three-dot operator opens a range, not a forwarding +================================================== + +def foo + ... 3 +end + +def bar + ...2 +end + +--- + +(program + (method + name: (identifier) + body: (body_statement + (range + end: (integer)))) + (method + name: (identifier) + body: (body_statement + (range + end: (integer))))) + =========================================== newline after range operator continues range =========================================== diff --git a/test/corpus/literals.txt b/test/corpus/literals.txt index 8f571621..dc6aaad2 100644 --- a/test/corpus/literals.txt +++ b/test/corpus/literals.txt @@ -1531,6 +1531,22 @@ un-terminated heredocs (heredoc_content) (heredoc_end))) +========================================== +un-terminated heredoc identifier +========================================== + +<<~"BASH + if the string inside is too short it doesn't crash + but I haven't found exactly how many chars is the problem + + it needs this line +BASH + +--- + +(program + (heredoc_beginning)) + ================================= no interpolation or escape sequences in single quoted heredoc ================================= From b71b8ee219e900acd5a7727f22d282531fdf0dea Mon Sep 17 00:00:00 2001 From: Mark Tareshawty Date: Mon, 24 Aug 2026 08:56:04 -0400 Subject: [PATCH 2/3] Drop duplicate range test and use the full heredoc reproducer The `def foo; ... 3; end` case is already covered verbatim in test/corpus/declarations.txt, so the added expressions.txt copy was redundant. The heredoc case had been shortened by one repeated line pair, which drops it below the scanner state size needed to trigger the deserialization assertion it is meant to guard. Use the complete source from the issue instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ac21705f-befb-4606-9c83-657e3e9ea0dc --- examples | 1 + test/corpus/expressions.txt | 26 -------------------------- test/corpus/literals.txt | 5 ++++- 3 files changed, 5 insertions(+), 27 deletions(-) create mode 120000 examples diff --git a/examples b/examples new file mode 120000 index 00000000..5ff00cae --- /dev/null +++ b/examples @@ -0,0 +1 @@ +/Users/tarebyte/src/tree-sitter/tree-sitter-ruby/examples \ No newline at end of file diff --git a/test/corpus/expressions.txt b/test/corpus/expressions.txt index 992925f6..5ed1f4d0 100644 --- a/test/corpus/expressions.txt +++ b/test/corpus/expressions.txt @@ -640,32 +640,6 @@ x.(123)(456) --- -================================================== -three-dot operator opens a range, not a forwarding -================================================== - -def foo - ... 3 -end - -def bar - ...2 -end - ---- - -(program - (method - name: (identifier) - body: (body_statement - (range - end: (integer)))) - (method - name: (identifier) - body: (body_statement - (range - end: (integer))))) - =========================================== newline after range operator continues range =========================================== diff --git a/test/corpus/literals.txt b/test/corpus/literals.txt index dc6aaad2..1e9348d3 100644 --- a/test/corpus/literals.txt +++ b/test/corpus/literals.txt @@ -1532,13 +1532,16 @@ un-terminated heredocs (heredoc_end))) ========================================== -un-terminated heredoc identifier +un-terminated heredoc identifier does not crash the scanner ========================================== <<~"BASH if the string inside is too short it doesn't crash but I haven't found exactly how many chars is the problem + if the string inside is too short it doesn't crash + but I haven't found exactly how many chars is the problem + it needs this line BASH From 4a0293c2d8fcf06d232528c57d991d1c2f52c9e6 Mon Sep 17 00:00:00 2001 From: Mark Tareshawty Date: Mon, 24 Aug 2026 10:39:19 -0400 Subject: [PATCH 3/3] Remove accidentally committed examples symlink The examples directory is a local checkout of the ruby/spec corpus used for differential testing. A symlink to it was committed by mistake; it points outside the repository and is meaningless to anyone else. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ac21705f-befb-4606-9c83-657e3e9ea0dc --- examples | 1 - 1 file changed, 1 deletion(-) delete mode 120000 examples diff --git a/examples b/examples deleted file mode 120000 index 5ff00cae..00000000 --- a/examples +++ /dev/null @@ -1 +0,0 @@ -/Users/tarebyte/src/tree-sitter/tree-sitter-ruby/examples \ No newline at end of file