mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
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:
parent
d6437fec0b
commit
363d3d57d7
17 changed files with 48 additions and 19 deletions
|
|
@ -1326,6 +1326,8 @@ pub struct DebuggerStatement {
|
||||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||||
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
|
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
|
||||||
pub struct BindingPattern<'a> {
|
pub struct BindingPattern<'a> {
|
||||||
|
#[cfg_attr(feature = "serialize", serde(flatten))]
|
||||||
|
pub span: Span,
|
||||||
// serde(flatten) the attributes because estree has no `BindingPattern`
|
// serde(flatten) the attributes because estree has no `BindingPattern`
|
||||||
#[cfg_attr(feature = "serialize", serde(flatten))]
|
#[cfg_attr(feature = "serialize", serde(flatten))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
|
|
|
||||||
|
|
@ -1189,11 +1189,12 @@ impl<'a> AstBuilder<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn binding_pattern(
|
pub fn binding_pattern(
|
||||||
self,
|
self,
|
||||||
|
span: Span,
|
||||||
kind: BindingPatternKind<'a>,
|
kind: BindingPatternKind<'a>,
|
||||||
type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
|
type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
|
||||||
optional: bool,
|
optional: bool,
|
||||||
) -> BindingPattern<'a> {
|
) -> BindingPattern<'a> {
|
||||||
BindingPattern { kind, type_annotation, optional }
|
BindingPattern { span, kind, type_annotation, optional }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -1254,6 +1255,7 @@ impl<'a> AstBuilder<'a> {
|
||||||
) -> BindingPattern<'a> {
|
) -> BindingPattern<'a> {
|
||||||
let pattern = self.alloc(AssignmentPattern { span, left, right });
|
let pattern = self.alloc(AssignmentPattern { span, left, right });
|
||||||
BindingPattern {
|
BindingPattern {
|
||||||
|
span,
|
||||||
kind: BindingPatternKind::AssignmentPattern(pattern),
|
kind: BindingPatternKind::AssignmentPattern(pattern),
|
||||||
type_annotation: None,
|
type_annotation: None,
|
||||||
optional: false,
|
optional: false,
|
||||||
|
|
|
||||||
|
|
@ -871,8 +871,8 @@ impl<'a> Hash for CatchClause<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> BindingPattern<'a> {
|
impl<'a> BindingPattern<'a> {
|
||||||
pub fn new_with_kind(kind: BindingPatternKind<'a>) -> Self {
|
pub fn new_with_kind(span: Span, kind: BindingPatternKind<'a>) -> Self {
|
||||||
Self { kind, type_annotation: None, optional: false }
|
Self { span, kind, type_annotation: None, optional: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_identifier(&self) -> Option<Atom<'a>> {
|
pub fn get_identifier(&self) -> Option<Atom<'a>> {
|
||||||
|
|
|
||||||
|
|
@ -505,7 +505,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
kind: BindingPatternKind<'a>,
|
kind: BindingPatternKind<'a>,
|
||||||
type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
|
type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
|
||||||
) -> Box<'a, FormalParameters<'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 =
|
let parameter =
|
||||||
self.ast.formal_parameter(SPAN, pattern, None, false, false, self.ast.new_vec());
|
self.ast.formal_parameter(SPAN, pattern, None, false, false, self.ast.new_vec());
|
||||||
let items = self.ast.new_vec_single(parameter);
|
let items = self.ast.new_vec_single(parameter);
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
|| self.ast.copy(&decl.id),
|
|| self.ast.copy(&decl.id),
|
||||||
|ts_type| {
|
|ts_type| {
|
||||||
self.ast.binding_pattern(
|
self.ast.binding_pattern(
|
||||||
|
SPAN,
|
||||||
self.ast.copy(&decl.id.kind),
|
self.ast.copy(&decl.id.kind),
|
||||||
Some(self.ast.ts_type_annotation(SPAN, ts_type)),
|
Some(self.ast.ts_type_annotation(SPAN, ts_type)),
|
||||||
decl.id.optional,
|
decl.id.optional,
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
});
|
});
|
||||||
|
|
||||||
pattern = self.ast.binding_pattern(
|
pattern = self.ast.binding_pattern(
|
||||||
|
SPAN,
|
||||||
self.ast.copy(&pattern.kind),
|
self.ast.copy(&pattern.kind),
|
||||||
type_annotation,
|
type_annotation,
|
||||||
// if it's assignment pattern, it's optional
|
// if it's assignment pattern, it's optional
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,8 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
self.error(default_export_inferred(expr.span()));
|
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
|
let declarations = self
|
||||||
.ast
|
.ast
|
||||||
.new_vec_single(self.ast.variable_declarator(SPAN, kind, id, None, true));
|
.new_vec_single(self.ast.variable_declarator(SPAN, kind, id, None, true));
|
||||||
|
|
|
||||||
|
|
@ -216,9 +216,10 @@ impl<'a> ParserImpl<'a> {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => 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 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);
|
let formal_parameter = self.ast.plain_formal_parameter(params_span, pattern);
|
||||||
self.ast.formal_parameters(
|
self.ast.formal_parameters(
|
||||||
params_span,
|
params_span,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ impl<'a> ParserImpl<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
allow_question: bool,
|
allow_question: bool,
|
||||||
) -> Result<BindingPattern<'a>> {
|
) -> Result<BindingPattern<'a>> {
|
||||||
|
let span = self.start_span();
|
||||||
let mut kind = self.parse_binding_pattern_kind()?;
|
let mut kind = self.parse_binding_pattern_kind()?;
|
||||||
let optional =
|
let optional =
|
||||||
if allow_question && self.ts_enabled() { self.eat(Kind::Question) } else { false };
|
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 {
|
if let Some(type_annotation) = &type_annotation {
|
||||||
Self::extend_binding_pattern_span_end(type_annotation.span, &mut kind);
|
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>> {
|
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
|
// The span is not extended to its type_annotation
|
||||||
let type_annotation = self.parse_ts_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`, .
|
// Rest element does not allow `= initializer`, .
|
||||||
let argument = self
|
let argument = self
|
||||||
.context(Context::In, Context::empty(), |p| p.parse_initializer(init_span, pattern))?;
|
.context(Context::In, Context::empty(), |p| p.parse_initializer(init_span, pattern))?;
|
||||||
|
|
@ -109,7 +110,7 @@ impl<'a> ParserImpl<'a> {
|
||||||
shorthand = true;
|
shorthand = true;
|
||||||
let binding_identifier = BindingIdentifier::new(ident.span, ident.name.clone());
|
let binding_identifier = BindingIdentifier::new(ident.span, ident.name.clone());
|
||||||
let identifier = self.ast.binding_pattern_identifier(binding_identifier);
|
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))?
|
self.context(Context::In, Context::empty(), |p| p.parse_initializer(span, left))?
|
||||||
} else {
|
} else {
|
||||||
return Err(self.unexpected());
|
return Err(self.unexpected());
|
||||||
|
|
|
||||||
|
|
@ -114,9 +114,17 @@ impl<'a> ParserImpl<'a> {
|
||||||
if let Some(type_annotation) = &type_annotation {
|
if let Some(type_annotation) = &type_annotation {
|
||||||
Self::extend_binding_pattern_span_end(type_annotation.span, &mut binding_kind);
|
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 {
|
} 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 =
|
let init =
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ impl<'a> ArrowFunctions<'a> {
|
||||||
|
|
||||||
if let Some(id) = &self.this_var {
|
if let Some(id) = &self.this_var {
|
||||||
let binding_pattern = self.ctx.ast.binding_pattern(
|
let binding_pattern = self.ctx.ast.binding_pattern(
|
||||||
|
SPAN,
|
||||||
self.ctx.ast.binding_pattern_identifier(id.create_binding_identifier()),
|
self.ctx.ast.binding_pattern_identifier(id.create_binding_identifier()),
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ impl<'a> ModuleImports<'a> {
|
||||||
name: name.imported,
|
name: name.imported,
|
||||||
symbol_id: Cell::new(Some(name.symbol_id)),
|
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 decl = {
|
||||||
let init = self.ast.call_expression(SPAN, callee, args, false, None);
|
let init = self.ast.call_expression(SPAN, callee, args, false, None);
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ impl<'a> ReactJsxSource<'a> {
|
||||||
let id = {
|
let id = {
|
||||||
let ident = filename_var.create_binding_identifier();
|
let ident = filename_var.create_binding_identifier();
|
||||||
let ident = self.ctx.ast.binding_pattern_identifier(ident);
|
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 decl = {
|
||||||
let string = self.ctx.ast.string_literal(SPAN, &self.ctx.source_path.to_string_lossy());
|
let string = self.ctx.ast.string_literal(SPAN, &self.ctx.source_path.to_string_lossy());
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ impl<'a> TypeScriptEnum<'a> {
|
||||||
let span = decl.span;
|
let span = decl.span;
|
||||||
let ident = decl.id.clone();
|
let ident = decl.id.clone();
|
||||||
let kind = self.ctx.ast.binding_pattern_identifier(ident);
|
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) => {
|
// ((Foo) => {
|
||||||
let params =
|
let params =
|
||||||
|
|
@ -127,7 +127,7 @@ impl<'a> TypeScriptEnum<'a> {
|
||||||
|
|
||||||
let binding_identifier = BindingIdentifier::new(SPAN, enum_name.clone());
|
let binding_identifier = BindingIdentifier::new(SPAN, enum_name.clone());
|
||||||
let binding_pattern_kind = self.ctx.ast.binding_pattern_identifier(binding_identifier);
|
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 =
|
let decl =
|
||||||
self.ctx.ast.variable_declarator(SPAN, kind, binding, Some(call_expression), false);
|
self.ctx.ast.variable_declarator(SPAN, kind, binding, Some(call_expression), false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ impl<'a> TypeScript<'a> {
|
||||||
let decls = {
|
let decls = {
|
||||||
let binding_identifier = BindingIdentifier::new(SPAN, decl.id.name.clone());
|
let binding_identifier = BindingIdentifier::new(SPAN, decl.id.name.clone());
|
||||||
let binding_pattern_kind = self.ctx.ast.binding_pattern_identifier(binding_identifier);
|
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 decl_span = decl.span;
|
||||||
|
|
||||||
let init = match &mut decl.module_reference {
|
let init = match &mut decl.module_reference {
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ impl<'a> TypeScript<'a> {
|
||||||
let declarations = {
|
let declarations = {
|
||||||
let ident = BindingIdentifier::new(SPAN, name);
|
let ident = BindingIdentifier::new(SPAN, name);
|
||||||
let pattern_kind = self.ctx.ast.binding_pattern_identifier(ident);
|
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);
|
let decl = self.ctx.ast.variable_declarator(SPAN, kind, binding, None, false);
|
||||||
self.ctx.ast.new_vec_single(decl)
|
self.ctx.ast.new_vec_single(decl)
|
||||||
};
|
};
|
||||||
|
|
@ -314,7 +314,7 @@ impl<'a> TypeScript<'a> {
|
||||||
let params = {
|
let params = {
|
||||||
let ident =
|
let ident =
|
||||||
self.ctx.ast.binding_pattern_identifier(BindingIdentifier::new(SPAN, arg_name));
|
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 =
|
let items =
|
||||||
self.ctx.ast.new_vec_single(self.ctx.ast.plain_formal_parameter(SPAN, pattern));
|
self.ctx.ast.new_vec_single(self.ctx.ast.plain_formal_parameter(SPAN, pattern));
|
||||||
self.ctx.ast.formal_parameters(
|
self.ctx.ast.formal_parameters(
|
||||||
|
|
|
||||||
|
|
@ -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_KIND: usize = offset_of!(BindingPattern, kind);
|
||||||
pub(crate) const OFFSET_BINDING_PATTERN_TYPE_ANNOTATION: usize =
|
pub(crate) const OFFSET_BINDING_PATTERN_TYPE_ANNOTATION: usize =
|
||||||
offset_of!(BindingPattern, type_annotation);
|
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>);
|
pub struct BindingPatternWithoutKind<'a>(pub(crate) *const BindingPattern<'a>);
|
||||||
|
|
||||||
impl<'a> BindingPatternWithoutKind<'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]
|
#[inline]
|
||||||
pub fn type_annotation(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
pub fn type_annotation(&self) -> &Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -4951,6 +4957,11 @@ impl<'a> BindingPatternWithoutKind<'a> {
|
||||||
pub struct BindingPatternWithoutTypeAnnotation<'a>(pub(crate) *const BindingPattern<'a>);
|
pub struct BindingPatternWithoutTypeAnnotation<'a>(pub(crate) *const BindingPattern<'a>);
|
||||||
|
|
||||||
impl<'a> BindingPatternWithoutTypeAnnotation<'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]
|
#[inline]
|
||||||
pub fn kind(&self) -> &BindingPatternKind<'a> {
|
pub fn kind(&self) -> &BindingPatternKind<'a> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue