From ad44329286dc4c4348cff290e639bd5969602888 Mon Sep 17 00:00:00 2001 From: "Arend van Beelen jr." Date: Mon, 15 Jul 2024 21:59:05 +0200 Subject: [PATCH] fix(grit): match object literal (#3447) --- .../biome_grit_patterns/src/grit_binding.rs | 2 +- .../src/grit_target_node.rs | 49 +++++++++++++++++++ .../src/pattern_compiler/snippet_compiler.rs | 2 +- .../tests/specs/ts/objectLiteral.grit | 1 + .../tests/specs/ts/objectLiteral.snap | 23 +++++++++ .../tests/specs/ts/objectLiteral.ts | 7 +++ 6 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 crates/biome_grit_patterns/tests/specs/ts/objectLiteral.grit create mode 100644 crates/biome_grit_patterns/tests/specs/ts/objectLiteral.snap create mode 100644 crates/biome_grit_patterns/tests/specs/ts/objectLiteral.ts diff --git a/crates/biome_grit_patterns/src/grit_binding.rs b/crates/biome_grit_patterns/src/grit_binding.rs index b4c914024225..f00021e04a01 100644 --- a/crates/biome_grit_patterns/src/grit_binding.rs +++ b/crates/biome_grit_patterns/src/grit_binding.rs @@ -178,7 +178,7 @@ impl<'a> Binding<'a, GritQueryContext> for GritBinding<'a> { fn list_items(&self) -> Option> + Clone> { match self { - Self::Node(node) if node.is_list() => Some(node.children()), + Self::Node(node) if node.is_list() => Some(node.named_children()), _ => None, } } diff --git a/crates/biome_grit_patterns/src/grit_target_node.rs b/crates/biome_grit_patterns/src/grit_target_node.rs index 2482f43b076a..6af59685ae2e 100644 --- a/crates/biome_grit_patterns/src/grit_target_node.rs +++ b/crates/biome_grit_patterns/src/grit_target_node.rs @@ -216,6 +216,10 @@ impl<'a> GritTargetNode<'a> { }) } + pub fn named_children(&self) -> impl Iterator + Clone { + NamedChildrenIterator::new(self) + } + #[inline] pub fn end_byte(&self) -> u32 { self.text_trimmed_range().end().into() @@ -415,6 +419,47 @@ impl<'a> Iterator for ChildrenIterator<'a> { } } +#[derive(Clone, Debug)] +pub struct NamedChildrenIterator<'a> { + cursor: Option>, +} + +impl<'a> NamedChildrenIterator<'a> { + fn new(node: &GritTargetNode<'a>) -> Self { + let mut cursor = GritTargetNodeCursor::new(node); + let mut cursor = cursor.goto_first_child().then_some(cursor); + if let Some(c) = cursor.as_mut() { + while c.is_at_token() { + if !c.goto_next_sibling() { + cursor = None; + break; + } + } + } + Self { cursor } + } +} + +impl<'a> Iterator for NamedChildrenIterator<'a> { + type Item = GritTargetNode<'a>; + + fn next(&mut self) -> Option { + let c = self.cursor.as_mut()?; + let node = c.node(); + if c.goto_next_sibling() { + while c.is_at_token() { + if !c.goto_next_sibling() { + self.cursor = None; + break; + } + } + } else { + self.cursor = None; + } + Some(node) + } +} + #[derive(Clone, Debug)] struct GritTargetNodeCursor<'a> { node: GritTargetNode<'a>, @@ -428,6 +473,10 @@ impl<'a> GritTargetNodeCursor<'a> { root: node.clone(), } } + + fn is_at_token(&self) -> bool { + self.node.is_token() + } } impl<'a> AstCursor for GritTargetNodeCursor<'a> { diff --git a/crates/biome_grit_patterns/src/pattern_compiler/snippet_compiler.rs b/crates/biome_grit_patterns/src/pattern_compiler/snippet_compiler.rs index 6eec30001ed8..e1436e601e5c 100644 --- a/crates/biome_grit_patterns/src/pattern_compiler/snippet_compiler.rs +++ b/crates/biome_grit_patterns/src/pattern_compiler/snippet_compiler.rs @@ -259,7 +259,7 @@ fn pattern_arg_from_slot( if slot.contains_list() { let mut nodes_list: Vec> = match &slot { GritSyntaxSlot::Node(node) => node - .children() + .named_children() .map(|n| pattern_from_node(&n, context_range, range_map, context, is_rhs)) .collect::>()?, _ => Vec::new(), diff --git a/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.grit b/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.grit new file mode 100644 index 000000000000..6fd10ec14739 --- /dev/null +++ b/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.grit @@ -0,0 +1 @@ +`{ foo: 1, bar: "bar" }` diff --git a/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.snap b/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.snap new file mode 100644 index 000000000000..970052395b47 --- /dev/null +++ b/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.snap @@ -0,0 +1,23 @@ +--- +source: crates/biome_grit_patterns/tests/spec_tests.rs +expression: objectLiteral +--- +SnapshotResult { + messages: [], + matched_ranges: [ + Range { + start: Position { + line: 3, + column: 15, + }, + end: Position { + line: 6, + column: 6, + }, + start_byte: 42, + end_byte: 85, + }, + ], + rewritten_files: [], + created_files: [], +} diff --git a/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.ts b/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.ts new file mode 100644 index 000000000000..a29d06304775 --- /dev/null +++ b/crates/biome_grit_patterns/tests/specs/ts/objectLiteral.ts @@ -0,0 +1,7 @@ + +function objectLiteral() { + const a = { + foo: 1, + bar: "bar", + } +}