refactor(ast): add span field to the BindingPattern type. (#3855)

So we don't have to introduce a special case while generating `GetSpan` implementations for all of our Ast types.
This commit is contained in:
rzvxa 2024-06-23 16:00:40 +00:00
parent d6437fec0b
commit 363d3d57d7
17 changed files with 48 additions and 19 deletions

View file

@ -1326,6 +1326,8 @@ pub struct DebuggerStatement {
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
pub struct BindingPattern<'a> {
#[cfg_attr(feature = "serialize", serde(flatten))]
pub span: Span,
// serde(flatten) the attributes because estree has no `BindingPattern`
#[cfg_attr(feature = "serialize", serde(flatten))]
#[cfg_attr(

View file

@ -1189,11 +1189,12 @@ impl<'a> AstBuilder<'a> {
#[inline]
pub fn binding_pattern(
self,
span: Span,
kind: BindingPatternKind<'a>,
type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
optional: bool,
) -> BindingPattern<'a> {
BindingPattern { kind, type_annotation, optional }
BindingPattern { span, kind, type_annotation, optional }
}
#[inline]
@ -1254,6 +1255,7 @@ impl<'a> AstBuilder<'a> {
) -> BindingPattern<'a> {
let pattern = self.alloc(AssignmentPattern { span, left, right });
BindingPattern {
span,
kind: BindingPatternKind::AssignmentPattern(pattern),
type_annotation: None,
optional: false,

View file

@ -871,8 +871,8 @@ impl<'a> Hash for CatchClause<'a> {
}
impl<'a> BindingPattern<'a> {
pub fn new_with_kind(kind: BindingPatternKind<'a>) -> Self {
Self { kind, type_annotation: None, optional: false }
pub fn new_with_kind(span: Span, kind: BindingPatternKind<'a>) -> Self {
Self { span, kind, type_annotation: None, optional: false }
}
pub fn get_identifier(&self) -> Option<Atom<'a>> {

View file

@ -505,7 +505,7 @@ impl<'a> IsolatedDeclarations<'a> {
kind: BindingPatternKind<'a>,
type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
) -> Box<'a, FormalParameters<'a>> {
let pattern = BindingPattern { kind, type_annotation, optional: false };
let pattern = BindingPattern { span: SPAN, kind, type_annotation, optional: false };
let parameter =
self.ast.formal_parameter(SPAN, pattern, None, false, false, self.ast.new_vec());
let items = self.ast.new_vec_single(parameter);

View file

@ -95,6 +95,7 @@ impl<'a> IsolatedDeclarations<'a> {
|| self.ast.copy(&decl.id),
|ts_type| {
self.ast.binding_pattern(
SPAN,
self.ast.copy(&decl.id.kind),
Some(self.ast.ts_type_annotation(SPAN, ts_type)),
decl.id.optional,

View file

@ -99,6 +99,7 @@ impl<'a> IsolatedDeclarations<'a> {
});
pattern = self.ast.binding_pattern(
SPAN,
self.ast.copy(&pattern.kind),
type_annotation,
// if it's assignment pattern, it's optional

View file

@ -65,7 +65,8 @@ impl<'a> IsolatedDeclarations<'a> {
self.error(default_export_inferred(expr.span()));
}
let id = BindingPattern { kind: id, type_annotation, optional: false };
let id =
BindingPattern { span: SPAN, kind: id, type_annotation, optional: false };
let declarations = self
.ast
.new_vec_single(self.ast.variable_declarator(SPAN, kind, id, None, true));

View file

@ -216,9 +216,10 @@ impl<'a> ParserImpl<'a> {
}
_ => unreachable!(),
};
let params_span = self.end_span(ident.span);
let span = ident.span;
let params_span = self.end_span(span);
let ident = self.ast.binding_pattern_identifier(ident);
let pattern = self.ast.binding_pattern(ident, None, false);
let pattern = self.ast.binding_pattern(span, ident, None, false);
let formal_parameter = self.ast.plain_formal_parameter(params_span, pattern);
self.ast.formal_parameters(
params_span,

View file

@ -20,6 +20,7 @@ impl<'a> ParserImpl<'a> {
&mut self,
allow_question: bool,
) -> Result<BindingPattern<'a>> {
let span = self.start_span();
let mut kind = self.parse_binding_pattern_kind()?;
let optional =
if allow_question && self.ts_enabled() { self.eat(Kind::Question) } else { false };
@ -27,7 +28,7 @@ impl<'a> ParserImpl<'a> {
if let Some(type_annotation) = &type_annotation {
Self::extend_binding_pattern_span_end(type_annotation.span, &mut kind);
}
Ok(self.ast.binding_pattern(kind, type_annotation, optional))
Ok(self.ast.binding_pattern(self.end_span(span), kind, type_annotation, optional))
}
pub(super) fn parse_binding_pattern_kind(&mut self) -> Result<BindingPatternKind<'a>> {
@ -72,7 +73,7 @@ impl<'a> ParserImpl<'a> {
}
// The span is not extended to its type_annotation
let type_annotation = self.parse_ts_type_annotation()?;
let pattern = self.ast.binding_pattern(kind, type_annotation, false);
let pattern = self.ast.binding_pattern(self.end_span(span), kind, type_annotation, false);
// Rest element does not allow `= initializer`, .
let argument = self
.context(Context::In, Context::empty(), |p| p.parse_initializer(init_span, pattern))?;
@ -109,7 +110,7 @@ impl<'a> ParserImpl<'a> {
shorthand = true;
let binding_identifier = BindingIdentifier::new(ident.span, ident.name.clone());
let identifier = self.ast.binding_pattern_identifier(binding_identifier);
let left = self.ast.binding_pattern(identifier, None, false);
let left = self.ast.binding_pattern(ident.span, identifier, None, false);
self.context(Context::In, Context::empty(), |p| p.parse_initializer(span, left))?
} else {
return Err(self.unexpected());

View file

@ -114,9 +114,17 @@ impl<'a> ParserImpl<'a> {
if let Some(type_annotation) = &type_annotation {
Self::extend_binding_pattern_span_end(type_annotation.span, &mut binding_kind);
}
(self.ast.binding_pattern(binding_kind, type_annotation, optional), definite)
(
self.ast.binding_pattern(
self.end_span(span),
binding_kind,
type_annotation,
optional,
),
definite,
)
} else {
(self.ast.binding_pattern(binding_kind, None, false), false)
(self.ast.binding_pattern(self.end_span(span), binding_kind, None, false), false)
};
let init =

View file

@ -114,6 +114,7 @@ impl<'a> ArrowFunctions<'a> {
if let Some(id) = &self.this_var {
let binding_pattern = self.ctx.ast.binding_pattern(
SPAN,
self.ctx.ast.binding_pattern_identifier(id.create_binding_identifier()),
None,
false,

View file

@ -134,7 +134,7 @@ impl<'a> ModuleImports<'a> {
name: name.imported,
symbol_id: Cell::new(Some(name.symbol_id)),
};
self.ast.binding_pattern(self.ast.binding_pattern_identifier(ident), None, false)
self.ast.binding_pattern(SPAN, self.ast.binding_pattern_identifier(ident), None, false)
};
let decl = {
let init = self.ast.call_expression(SPAN, callee, args, false, None);

View file

@ -152,7 +152,7 @@ impl<'a> ReactJsxSource<'a> {
let id = {
let ident = filename_var.create_binding_identifier();
let ident = self.ctx.ast.binding_pattern_identifier(ident);
self.ctx.ast.binding_pattern(ident, None, false)
self.ctx.ast.binding_pattern(SPAN, ident, None, false)
};
let decl = {
let string = self.ctx.ast.string_literal(SPAN, &self.ctx.source_path.to_string_lossy());

View file

@ -67,7 +67,7 @@ impl<'a> TypeScriptEnum<'a> {
let span = decl.span;
let ident = decl.id.clone();
let kind = self.ctx.ast.binding_pattern_identifier(ident);
let id = self.ctx.ast.binding_pattern(kind, None, false);
let id = self.ctx.ast.binding_pattern(SPAN, kind, None, false);
// ((Foo) => {
let params =
@ -127,7 +127,7 @@ impl<'a> TypeScriptEnum<'a> {
let binding_identifier = BindingIdentifier::new(SPAN, enum_name.clone());
let binding_pattern_kind = self.ctx.ast.binding_pattern_identifier(binding_identifier);
let binding = self.ctx.ast.binding_pattern(binding_pattern_kind, None, false);
let binding = self.ctx.ast.binding_pattern(SPAN, binding_pattern_kind, None, false);
let decl =
self.ctx.ast.variable_declarator(SPAN, kind, binding, Some(call_expression), false);

View file

@ -35,7 +35,7 @@ impl<'a> TypeScript<'a> {
let decls = {
let binding_identifier = BindingIdentifier::new(SPAN, decl.id.name.clone());
let binding_pattern_kind = self.ctx.ast.binding_pattern_identifier(binding_identifier);
let binding = self.ctx.ast.binding_pattern(binding_pattern_kind, None, false);
let binding = self.ctx.ast.binding_pattern(SPAN, binding_pattern_kind, None, false);
let decl_span = decl.span;
let init = match &mut decl.module_reference {

View file

@ -282,7 +282,7 @@ impl<'a> TypeScript<'a> {
let declarations = {
let ident = BindingIdentifier::new(SPAN, name);
let pattern_kind = self.ctx.ast.binding_pattern_identifier(ident);
let binding = self.ctx.ast.binding_pattern(pattern_kind, None, false);
let binding = self.ctx.ast.binding_pattern(SPAN, pattern_kind, None, false);
let decl = self.ctx.ast.variable_declarator(SPAN, kind, binding, None, false);
self.ctx.ast.new_vec_single(decl)
};
@ -314,7 +314,7 @@ impl<'a> TypeScript<'a> {
let params = {
let ident =
self.ctx.ast.binding_pattern_identifier(BindingIdentifier::new(SPAN, arg_name));
let pattern = self.ctx.ast.binding_pattern(ident, None, false);
let pattern = self.ctx.ast.binding_pattern(SPAN, ident, None, false);
let items =
self.ctx.ast.new_vec_single(self.ctx.ast.plain_formal_parameter(SPAN, pattern));
self.ctx.ast.formal_parameters(

View file

@ -4922,6 +4922,7 @@ impl<'a> CatchParameterWithoutPattern<'a> {
}
}
pub(crate) const OFFSET_BINDING_PATTERN_SPAN: usize = offset_of!(BindingPattern, span);
pub(crate) const OFFSET_BINDING_PATTERN_KIND: usize = offset_of!(BindingPattern, kind);
pub(crate) const OFFSET_BINDING_PATTERN_TYPE_ANNOTATION: usize =
offset_of!(BindingPattern, type_annotation);
@ -4932,6 +4933,11 @@ pub(crate) const OFFSET_BINDING_PATTERN_OPTIONAL: usize = offset_of!(BindingPatt
pub struct BindingPatternWithoutKind<'a>(pub(crate) *const BindingPattern<'a>);
impl<'a> BindingPatternWithoutKind<'a> {
#[inline]
pub fn span(&self) -> &Span {
unsafe { &*((self.0 as *const u8).add(OFFSET_BINDING_PATTERN_SPAN) as *const Span) }
}
#[inline]
pub fn type_annotation(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
unsafe {
@ -4951,6 +4957,11 @@ impl<'a> BindingPatternWithoutKind<'a> {
pub struct BindingPatternWithoutTypeAnnotation<'a>(pub(crate) *const BindingPattern<'a>);
impl<'a> BindingPatternWithoutTypeAnnotation<'a> {
#[inline]
pub fn span(&self) -> &Span {
unsafe { &*((self.0 as *const u8).add(OFFSET_BINDING_PATTERN_SPAN) as *const Span) }
}
#[inline]
pub fn kind(&self) -> &BindingPatternKind<'a> {
unsafe {