Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

[Bug] tree-sitter-bash parses `$_` / `${_}` as variable_name instead of special_variable_name

Đang mở Phù hợp với người mới
#4,367 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
Dưới một giờ
Mức phù hợp với người mới
85/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
bash, typescript
Lĩnh vực
compilers

Hướng nghiên cứu

Bắt đầu trong src/parser.ts tại parseDollar() và parseExpansion(), nơi 0 được xử lý đặc biệt; áp dụng diff hai dòng để cũng coi _ là đặc biệt. Thêm các dòng fixture vào packages/tree-sitter-bash/test/fixtures/differential/expansions.txt. Chạy pnpm --filter @moonshot-ai/tree-sitter-bash test; hoàn thành nghĩa là bộ kiểm thử differential pass với special_variable_name cho _ đứng một mình.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

What issue are you seeing?

packages/tree-sitter-bash parses the special parameter $_ as a variable_name, while the reference grammar ([email protected], the parser this package is differentially compared against) parses a lone _ as a special_variable_name. So ourDump(source) !== referenceDump(source) for input the package claims byte-identical tree parity on.

echo $_:

ours:
program [0,7] "echo $_"
  command [0,7] "echo $_"
    command_name [0,4] "echo"
      word [0,4] "echo"
    simple_expansion [5,7] "$_"
      ($) [5,6] "$"
      variable_name [6,7] "_"

reference:
program [0,7] "echo $_"
  command [0,7] "echo $_"
    command_name [0,4] "echo"
      word [0,4] "echo"
    simple_expansion [5,7] "$_"
      ($) [5,6] "$"
      special_variable_name [6,7] "_"

Same divergence for echo ${_}, echo ${_#x}, "${_}", ${_:-d}, ${_=x}: the _ child is variable_name here, special_variable_name in the reference.

Not affected (both sides agree): $?, $#, $-, $!, $@, $*, $$, $0, $1; and $_a, ${_a}, $__, which are variable_name on both sides (the \w+ rule wins once another word character follows).

What steps can reproduce the bug?
  1. Append a fixture to packages/tree-sitter-bash/test/fixtures/differential/expansions.txt:
@match: echo $_ and ${_} are special parameters, $_a and ${_a} are not
echo $_ ${_} ${_#x} $_a ${_a}
===
  1. pnpm --filter @moonshot-ai/tree-sitter-bash test

The differential suite fails on that fixture with the diff above (echo $_a and echo ${_a} still match).

What is the expected behavior?

A lone _ after $, and a lone _ as an expansion body, should produce special_variable_name "_" — matching _special_variable_name in the reference grammar:

_special_variable_name: $ => alias(choice('*', '@', '?', '!', '#', '-', '$', '0', '_'), $.special_variable_name),
_simple_variable_name: $ => alias(/\w+/, $.variable_name),
Additional information

Root cause: src/grammar.ts already lists _ in SPECIAL_VARIABLES (['@', '*', '#', '?', '-', '$', '!', '0', '_']), but SPECIAL_VARIABLE_CHARS filters word characters out of it (they are normally matched by the \w+ rule), so the only place a lone word-character special parameter is recognized explicitly is:

  • src/parser.ts, parseDollar() — if (j === i + 2 && next === '0')
  • src/parser.ts, parseExpansion() — const special = nameEnd === j + 1 && this.source[j] === '0';

Both special-case 0 but not _. Proposed fix (two lines, plus comment wording):

-      if (j === i + 2 && next === '0') {
+      if (j === i + 2 && (next === '0' || next === '_')) {
...
-      const special = nameEnd === j + 1 && this.source[j] === '0';
+      const special = nameEnd === j + 1 && (this.source[j] === '0' || this.source[j] === '_');

With that fix and the fixtures above: pnpm --filter @moonshot-ai/tree-sitter-bash test passes (6 files, 868 tests, 677 of them differential), typecheck is clean, oxlint --type-aware reports nothing.

Scope/impact: no user-visible behavior changes — nothing in packages/agent-core-v2 branches on special_variable_name vs variable_name (the permission policies key on command / command_name / string_content, bashTargets.ts on program / list / pipeline / redirected_statement). This is a fidelity bug against the package's stated contract of matching the reference tree byte for byte. @moonshot-ai/tree-sitter-bash is private, so no changeset is added.

Reproduced on main @ 7ccac2b on Windows 11 x64 with Node 24.21.0 / pnpm 10.33.0.

I'd like to submit the PR for this one — please /approve if that is welcome.

Contribution
  • I am willing to submit a PR for this bug fix myself (please wait for maintainer approval in this issue first)
Ngôn ngữ chính
TypeScript
Star
7.9k
Fork
1.3k
Merge trung bình
1 ngày 7 giờ
Pull request đã merge (30 ngày)
96

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của MoonshotAI/kimi-code

Tất cả issue của MoonshotAI/kimi-code

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.