Skip to content

🐛 GritQL: Spread metavariable $... fails to match object members #7446

@rriski

Description

@rriski

Summary

The spread metavariable $... works correctly in arrays and function calls but fails for object literals.

Repro

Repro files
# test_spread_metavariable.ts
const _arr1 = [0, 1, 2];
const _arr2 = [1];
const _arr3 = ["a", 1, "b"];

const _obj1 = { key: 1, a: 2 };
const _obj2 = { key: 1 };
const _obj3 = { key: 1, x: true, y: false };

fn(1, 2, 3);
fn();
fn("hello", "world");
# spread_metavariable.grit
pattern spread_metavariable() {
  or {
    `[$..., 1, $...]`,
    `{ key: 1, $... }`,
    `fn($...)`
  }
}
# spread_metavariable_biome.grit
or {
  `[$..., 1, $...]`,
  `{ key: 1, $... }`,
  `fn($...)`
} as $value where {
  register_diagnostic(
    span = $value,
    message = "Spread metavariable match",
    severity = "error"
  )
}

Grit Output

» grit apply spread_metavariable
./test_spread_metavariable.ts
     1  const _arr1 = [0, 1, 2];
     5  const _obj1 = { key: 1, a: 2 };
     9  fn(1, 2, 3);

Processed X files and found 9 matches

Note

GritQL currently only matches obj1, not obj2 and obj3. This may or may not be a bug in Grit, but I believe all three should match.

Biome Plugin Output

» biome check --max-diagnostics 100

test_spread_metavariable.ts:1:15 plugin ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ✖ Spread metavariable match

  > 1 │ const _arr1 = [0, 1, 2];
      │               ^^^^^^^^^
    2 │ const _arr2 = [1];
    3 │ const _arr3 = ["a", 1, "b"];


test_spread_metavariable.ts:2:15 plugin ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ✖ Spread metavariable match

    1 │ const _arr1 = [0, 1, 2];
  > 2 │ const _arr2 = [1];
      │               ^^^
    3 │ const _arr3 = ["a", 1, "b"];
    4 │


test_spread_metavariable.ts:3:15 plugin ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ✖ Spread metavariable match

    1 │ const _arr1 = [0, 1, 2];
    2 │ const _arr2 = [1];
  > 3 │ const _arr3 = ["a", 1, "b"];
      │               ^^^^^^^^^^^^^
    4 │
    5 │ const _obj1 = { key: 1, a: 2 };


test_spread_metavariable.ts:9:1 plugin ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ✖ Spread metavariable match

     7 │ const _obj3 = { key: 1, x: true, y: false };
     8 │
   > 9 │ fn(1, 2, 3);
       │ ^^^^^^^^^^^
    10 │ fn();
    11 │ fn("hello", "world");


test_spread_metavariable.ts:10:1 plugin ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ✖ Spread metavariable match

     9 │ fn(1, 2, 3);
  > 10 │ fn();
       │ ^^^^
    11 │ fn("hello", "world");
    12 │


test_spread_metavariable.ts:11:1 plugin ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ✖ Spread metavariable match

     9 │ fn(1, 2, 3);
    10 │ fn();
  > 11 │ fn("hello", "world");
       │ ^^^^^^^^^^^^^^^^^^^^
    12 │

Found 6 errors.

Missing object diagnostics: No errors are reported, for obj1, obj2 or obj3. The pattern should find 9 total matches.

Code of Conduct

  • I agree to follow Biome's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    S-Needs triageStatus: this issue needs to be triaged

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions