Skip to content

Commit

Permalink
feat(regular_expression): implement GetSpan for RegExp AST nodes (#…
Browse files Browse the repository at this point in the history
…6056)

To make it easier to get the `Span` for some node in the Regex AST, I've implemented the `GetSpan` trait for all necessary structs.
  • Loading branch information
camchenry committed Sep 26, 2024
1 parent 60c52ba commit 8d026e1
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
5 changes: 3 additions & 2 deletions crates/oxc_regular_expression/examples/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ use oxc_regular_expression::{
visit::{RegExpAstKind, Visit},
Parser, ParserOptions,
};
use oxc_span::GetSpan;

struct TestVisitor;

impl Visit<'_> for TestVisitor {
fn enter_node(&mut self, kind: RegExpAstKind) {
println!("enter_node: {kind:?}");
println!("enter_node: {:?} {kind:?}", kind.span());
}

fn leave_node(&mut self, kind: RegExpAstKind) {
println!("leave_node: {kind:?}");
println!("leave_node: {:?} {kind:?}", kind.span());
}
}

Expand Down
36 changes: 35 additions & 1 deletion crates/oxc_regular_expression/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

use oxc_allocator::{Box, CloneIn, Vec};
use oxc_ast_macros::ast;
use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, Span};
use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, Span};
#[cfg(feature = "serialize")]
use serde::Serialize;
#[cfg(feature = "serialize")]
Expand Down Expand Up @@ -92,6 +92,26 @@ pub enum Term<'a> {
NamedReference(Box<'a, NamedReference<'a>>) = 11,
}

impl<'a> GetSpan for Term<'a> {
#[inline]
fn span(&self) -> Span {
match self {
Term::BoundaryAssertion(it) => it.span,
Term::LookAroundAssertion(it) => it.span,
Term::Quantifier(it) => it.span,
Term::Character(it) => it.span,
Term::Dot(it) => it.span,
Term::CharacterClassEscape(it) => it.span,
Term::UnicodePropertyEscape(it) => it.span,
Term::CharacterClass(it) => it.span,
Term::CapturingGroup(it) => it.span,
Term::IgnoreGroup(it) => it.span,
Term::IndexedReference(it) => it.span,
Term::NamedReference(it) => it.span,
}
}
}

/// Simple form of assertion.
/// e.g. `^`, `$`, `\b`, `\B`
#[ast]
Expand Down Expand Up @@ -275,6 +295,20 @@ pub enum CharacterClassContents<'a> {
ClassStringDisjunction(Box<'a, ClassStringDisjunction<'a>>) = 5,
}

impl<'a> GetSpan for CharacterClassContents<'a> {
#[inline]
fn span(&self) -> Span {
match self {
CharacterClassContents::CharacterClassRange(it) => it.span,
CharacterClassContents::CharacterClassEscape(it) => it.span,
CharacterClassContents::UnicodePropertyEscape(it) => it.span,
CharacterClassContents::Character(it) => it.span,
CharacterClassContents::NestedCharacterClass(it) => it.span,
CharacterClassContents::ClassStringDisjunction(it) => it.span,
}
}
}

/// `-` separated range of characters.
/// e.g. `a-z`, `A-Z`, `0-9`
#[ast]
Expand Down
29 changes: 29 additions & 0 deletions crates/oxc_regular_expression/src/visit.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(unused_variables, clippy::wildcard_imports)]
use oxc_span::{GetSpan, Span};
use walk::walk_pattern;

use crate::ast::{
Expand Down Expand Up @@ -33,6 +34,34 @@ pub enum RegExpAstKind<'a> {
NamedReference(&'a NamedReference<'a>),
}

impl<'a> GetSpan for RegExpAstKind<'a> {
#[inline]
fn span(&self) -> Span {
match self {
Self::Pattern(it) => it.span,
Self::Disjunction(it) => it.span,
Self::Alternative(it) => it.span,
Self::Term(it) => GetSpan::span(*it),
Self::LookAroundAssertion(it) => it.span,
Self::Quantifier(it) => it.span,
Self::CapturingGroup(it) => it.span,
Self::IgnoreGroup(it) => it.span,
Self::BoundaryAssertion(it) => it.span,
Self::Character(it) => it.span,
Self::Dot(it) => it.span,
Self::CharacterClassEscape(it) => it.span,
Self::UnicodePropertyEscape(it) => it.span,
Self::CharacterClass(it) => it.span,
Self::CharacterClassContents(it) => GetSpan::span(*it),
Self::CharacterClassRange(it) => it.span,
Self::CharacterClassStringDisjunction(it) => it.span,
Self::CharacterClassString(it) => it.span,
Self::IndexedReference(it) => it.span,
Self::NamedReference(it) => it.span,
}
}
}

/// RegEx syntax tree traversal
pub trait Visit<'a>: Sized {
#[inline]
Expand Down

0 comments on commit 8d026e1

Please sign in to comment.