Skip to content

Commit 97a5c79

Browse files
authored
refactor(es/parser): Remove span swap operation in parser (#10854)
1 parent c49ce1e commit 97a5c79

File tree

22 files changed

+113
-81
lines changed

22 files changed

+113
-81
lines changed

.changeset/eighty-pigs-drum.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
swc_common: patch
3+
swc_ecma_lexer: major
4+
swc_ecma_compat_es2015: patch
5+
---
6+
7+
refactor(es/parser): rm span swap in parser

crates/swc_common/src/syntax_pos.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,18 @@ impl Span {
406406
Span { lo, hi }
407407
}
408408

409+
#[inline]
410+
pub fn new_with_checked(lo: BytePos, hi: BytePos) -> Self {
411+
debug_assert!(lo <= hi, "lo: {lo:#?}, hi: {hi:#?}");
412+
Span { lo, hi }
413+
}
414+
409415
#[inline]
410416
pub fn with_lo(&self, lo: BytePos) -> Span {
411417
Span::new(lo, self.hi)
412418
}
413419

414-
#[inline]
420+
#[inline(always)]
415421
pub fn hi(self) -> BytePos {
416422
self.hi
417423
}

crates/swc_ecma_compat_es2015/src/generator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2642,7 +2642,7 @@ impl Generator {
26422642
.push(expr);
26432643
}
26442644
return Invalid {
2645-
span: Span::new(BytePos(label.0 as _), BytePos(label.0 as _)),
2645+
span: Span::new_with_checked(BytePos(label.0 as _), BytePos(label.0 as _)),
26462646
}
26472647
.into();
26482648
}

crates/swc_ecma_lexer/src/common/lexer/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ pub trait Lexer<'a, TokenAndSpan>: Tokens<TokenAndSpan> + Sized {
267267
let s = unsafe { self.input_slice(slice_start, end) };
268268
let cmt = swc_common::comments::Comment {
269269
kind: swc_common::comments::CommentKind::Line,
270-
span: Span::new(start, end),
270+
span: Span::new_with_checked(start, end),
271271
text: self.atom(s),
272272
};
273273

@@ -298,7 +298,7 @@ pub trait Lexer<'a, TokenAndSpan>: Tokens<TokenAndSpan> + Sized {
298298
};
299299
let cmt = swc_common::comments::Comment {
300300
kind: swc_common::comments::CommentKind::Line,
301-
span: Span::new(start, end),
301+
span: Span::new_with_checked(start, end),
302302
text: self.atom(s),
303303
};
304304

@@ -371,7 +371,7 @@ pub trait Lexer<'a, TokenAndSpan>: Tokens<TokenAndSpan> + Sized {
371371
self.state_mut().mark_had_line_break();
372372
}
373373
let end_pos = self.input().end_pos();
374-
let span = Span::new(end_pos, end_pos);
374+
let span = Span::new_with_checked(end_pos, end_pos);
375375
self.emit_error_span(span, SyntaxError::UnterminatedBlockComment);
376376
return;
377377
}
@@ -407,7 +407,7 @@ pub trait Lexer<'a, TokenAndSpan>: Tokens<TokenAndSpan> + Sized {
407407
let s = &src[..src.len() - 2];
408408
let cmt = Comment {
409409
kind: CommentKind::Block,
410-
span: Span::new(start, end),
410+
span: Span::new_with_checked(start, end),
411411
text: self.atom(s),
412412
};
413413

@@ -807,7 +807,7 @@ pub trait Lexer<'a, TokenAndSpan>: Tokens<TokenAndSpan> + Sized {
807807
.checked_mul(radix as u32)
808808
.and_then(|v| v.checked_add(val))
809809
.ok_or_else(|| {
810-
let span = Span::new(start, start);
810+
let span = Span::new_with_checked(start, start);
811811
crate::error::Error::new(span, SyntaxError::InvalidUnicodeEscape)
812812
})?;
813813

@@ -2144,9 +2144,9 @@ pub trait Lexer<'a, TokenAndSpan>: Tokens<TokenAndSpan> + Sized {
21442144
}
21452145

21462146
pub fn pos_span(p: BytePos) -> Span {
2147-
Span::new(p, p)
2147+
Span::new_with_checked(p, p)
21482148
}
21492149

21502150
pub fn fixed_len_span(p: BytePos, len: u32) -> Span {
2151-
Span::new(p, p + BytePos(len))
2151+
Span::new_with_checked(p, p + BytePos(len))
21522152
}

crates/swc_ecma_lexer/src/common/parser/buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ pub trait Buffer<'a> {
201201
.get_cur()
202202
.map(|item| item.span())
203203
.unwrap_or(self.prev_span());
204-
Span::new(data.lo, data.hi)
204+
Span::new_with_checked(data.lo, data.hi)
205205
}
206206

207207
/// Returns last byte position of previous token.

crates/swc_ecma_lexer/src/common/parser/class_and_fn.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,9 +1508,8 @@ fn parse_class_body<'a, P: Parser<'a>>(p: &mut P) -> PResult<Vec<ClassMember>> {
15081508
while !eof!(p) && !p.input_mut().is(&P::Token::RBRACE) {
15091509
if p.input_mut().eat(&P::Token::SEMI) {
15101510
let span = p.input().prev_span();
1511-
elems.push(ClassMember::Empty(EmptyStmt {
1512-
span: Span::new(span.lo, span.hi),
1513-
}));
1511+
debug_assert!(span.lo <= span.hi);
1512+
elems.push(ClassMember::Empty(EmptyStmt { span }));
15141513
continue;
15151514
}
15161515
let elem = p.do_inside_of_context(Context::AllowDirectSuper, parse_class_member)?;
@@ -1667,12 +1666,12 @@ fn parse_class_inner<'a, P: Parser<'a>>(
16671666
} else {
16681667
expect!(p, &P::Token::RBRACE);
16691668
}
1670-
let end = p.last_pos();
16711669

1670+
let span = p.span(class_start);
16721671
Ok((
16731672
ident,
16741673
Box::new(Class {
1675-
span: Span::new(class_start, end),
1674+
span,
16761675
decorators,
16771676
is_abstract: false,
16781677
type_params,

crates/swc_ecma_lexer/src/common/parser/expr.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ fn parse_assignment_expr_base<'a, P: Parser<'a>>(p: &mut P) -> PResult<Box<Expr>
408408
ref mut type_params,
409409
..
410410
}) => {
411-
*span = Span::new(type_parameters.span.lo, span.hi);
411+
*span = Span::new_with_checked(type_parameters.span.lo, span.hi);
412412
*type_params = Some(type_parameters);
413413
}
414414
_ => unexpected!(p, "("),
@@ -547,7 +547,7 @@ fn parse_cond_expr<'a, P: Parser<'a>>(p: &mut P) -> PResult<Box<Expr>> {
547547
p.do_outside_of_context(Context::WillExpectColonForCond, parse_assignment_expr)
548548
})?;
549549

550-
let span = Span::new(start, alt.span_hi());
550+
let span = Span::new_with_checked(start, alt.span_hi());
551551
Ok(CondExpr {
552552
span,
553553
test,
@@ -772,10 +772,10 @@ fn parse_subscript<'a, P: Parser<'a>>(
772772
let bracket_lo = p.input().prev_span().lo;
773773
let prop = p.allow_in_expr(|p| p.parse_expr())?;
774774
expect!(p, &P::Token::RBRACKET);
775-
let span = Span::new(obj.span_lo(), p.input().last_pos());
775+
let span = Span::new_with_checked(obj.span_lo(), p.input().last_pos());
776776
debug_assert_eq!(obj.span_lo(), span.lo());
777777
let prop = ComputedPropName {
778-
span: Span::new(bracket_lo, p.input().last_pos()),
778+
span: Span::new_with_checked(bracket_lo, p.input().last_pos()),
779779
expr: prop,
780780
};
781781

@@ -1474,7 +1474,7 @@ fn parse_bin_op_recursively_inner<'a, P: Parser<'a>>(
14741474
}
14751475

14761476
let node = BinExpr {
1477-
span: Span::new(left.span_lo(), right.span_hi()),
1477+
span: Span::new_with_checked(left.span_lo(), right.span_hi()),
14781478
op,
14791479
left,
14801480
right,
@@ -1521,7 +1521,7 @@ pub(crate) fn parse_unary_expr<'a, P: Parser<'a>>(p: &mut P) -> PResult<Box<Expr
15211521
};
15221522

15231523
let arg = p.parse_unary_expr()?;
1524-
let span = Span::new(start, arg.span_hi());
1524+
let span = Span::new_with_checked(start, arg.span_hi());
15251525
p.check_assign_target(&arg, false);
15261526

15271527
return Ok(UpdateExpr {
@@ -1563,7 +1563,7 @@ pub(crate) fn parse_unary_expr<'a, P: Parser<'a>>(p: &mut P) -> PResult<Box<Expr
15631563
Err(err) => {
15641564
p.emit_error(err);
15651565
Invalid {
1566-
span: Span::new(arg_start, arg_start),
1566+
span: Span::new_with_checked(arg_start, arg_start),
15671567
}
15681568
.into()
15691569
}
@@ -1576,7 +1576,7 @@ pub(crate) fn parse_unary_expr<'a, P: Parser<'a>>(p: &mut P) -> PResult<Box<Expr
15761576
}
15771577

15781578
return Ok(UnaryExpr {
1579-
span: Span::new(start, arg.span_hi()),
1579+
span: Span::new_with_checked(start, arg.span_hi()),
15801580
op,
15811581
arg,
15821582
}
@@ -1923,7 +1923,7 @@ fn parse_args_or_pats_inner<'a, P: Parser<'a>>(
19231923
arg = ExprOrSpread {
19241924
spread: None,
19251925
expr: CondExpr {
1926-
span: Span::new(start, alt.span_hi()),
1926+
span: Span::new_with_checked(start, alt.span_hi()),
19271927
test,
19281928
cons,
19291929
alt,
@@ -1988,7 +1988,7 @@ fn parse_args_or_pats_inner<'a, P: Parser<'a>>(
19881988
}) => {
19891989
let new_type_ann = try_parse_ts_type_ann(p)?;
19901990
if new_type_ann.is_some() {
1991-
*span = Span::new(pat_start, p.input().prev_span().hi);
1991+
*span = Span::new_with_checked(pat_start, p.input().prev_span().hi);
19921992
}
19931993
*type_ann = new_type_ann;
19941994
}
@@ -2263,7 +2263,7 @@ pub fn parse_paren_expr_or_arrow_fn<'a, P: Parser<'a>>(
22632263
if expr_or_spreads.is_empty() {
22642264
syntax_error!(
22652265
p,
2266-
Span::new(expr_start, p.last_pos()),
2266+
Span::new_with_checked(expr_start, p.last_pos()),
22672267
SyntaxError::EmptyParenExpr
22682268
);
22692269
}
@@ -2301,7 +2301,7 @@ pub fn parse_paren_expr_or_arrow_fn<'a, P: Parser<'a>>(
23012301

23022302
// span of sequence expression should not include '(', ')'
23032303
let seq_expr = SeqExpr {
2304-
span: Span::new(
2304+
span: Span::new_with_checked(
23052305
exprs.first().unwrap().span_lo(),
23062306
exprs.last().unwrap().span_hi(),
23072307
),

crates/swc_ecma_lexer/src/common/parser/jsx.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ fn parse_jsx_namespaced_name<'a, P: Parser<'a>>(p: &mut P) -> PResult<JSXAttrNam
8686
}
8787
let name = parse_jsx_ident(p).map(IdentName::from)?;
8888
Ok(JSXAttrName::JSXNamespacedName(JSXNamespacedName {
89-
span: Span::new(start, name.span.hi),
89+
span: Span::new_with_checked(start, name.span.hi),
9090
ns,
9191
name,
9292
}))
@@ -125,7 +125,7 @@ fn parse_jsx_empty_expr<'a>(p: &mut impl Parser<'a>) -> JSXEmptyExpr {
125125
debug_assert!(p.input().syntax().jsx());
126126
let start = p.input_mut().cur_pos();
127127
JSXEmptyExpr {
128-
span: Span::new(start, start),
128+
span: Span::new_with_checked(start, start),
129129
}
130130
}
131131

crates/swc_ecma_lexer/src/common/parser/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ pub trait Parser<'a>: Sized + Clone {
270270
start <= end,
271271
"assertion failed: (span.start <= span.end). start = {start:?}, end = {end:?}",
272272
);
273-
Span::new(start, end)
273+
Span::new_with_checked(start, end)
274274
}
275275

276276
#[inline(always)]
@@ -525,6 +525,6 @@ pub fn eof_error<'a, P: Parser<'a>>(p: &mut P) -> crate::error::Error {
525525
"Parser should not call throw_eof_error() without knowing current token"
526526
);
527527
let pos = p.input().end_pos();
528-
let last = Span::new(pos, pos);
528+
let last = Span { lo: pos, hi: pos };
529529
crate::error::Error::new(last, crate::error::SyntaxError::Eof)
530530
}

crates/swc_ecma_lexer/src/common/parser/module_item.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,17 @@ fn parse_named_export_specifier<'a, P: Parser<'a>>(
138138
p.emit_err(orig_ident.span, SyntaxError::TS2207);
139139
}
140140

141+
debug_assert!(start <= orig_ident.span.hi());
141142
return Ok(ExportNamedSpecifier {
142-
span: Span::new(start, orig_ident.span.hi()),
143+
span: Span::new_with_checked(start, orig_ident.span.hi()),
143144
orig: ModuleExportName::Ident(possibly_orig),
144145
exported: Some(ModuleExportName::Ident(exported)),
145146
is_type_only: true,
146147
});
147148
} else {
148149
// `export { type as as }`
149150
return Ok(ExportNamedSpecifier {
150-
span: Span::new(start, orig_ident.span.hi()),
151+
span: Span::new_with_checked(start, orig_ident.span.hi()),
151152
orig: ModuleExportName::Ident(orig_ident),
152153
exported: Some(ModuleExportName::Ident(maybe_as)),
153154
is_type_only: false,
@@ -156,7 +157,7 @@ fn parse_named_export_specifier<'a, P: Parser<'a>>(
156157
} else {
157158
// `export { type as xxx }`
158159
return Ok(ExportNamedSpecifier {
159-
span: Span::new(start, orig_ident.span.hi()),
160+
span: Span::new_with_checked(start, orig_ident.span.hi()),
160161
orig: ModuleExportName::Ident(orig_ident),
161162
exported: Some(ModuleExportName::Ident(maybe_as)),
162163
is_type_only: false,
@@ -261,15 +262,15 @@ fn parse_import_specifier<'a, P: Parser<'a>>(
261262
}
262263

263264
return Ok(ImportSpecifier::Named(ImportNamedSpecifier {
264-
span: Span::new(start, orig_name.span.hi()),
265+
span: Span::new_with_checked(start, orig_name.span.hi()),
265266
local,
266267
imported: Some(ModuleExportName::Ident(possibly_orig_name)),
267268
is_type_only: true,
268269
}));
269270
} else {
270271
// `import { type as as } from 'mod'`
271272
return Ok(ImportSpecifier::Named(ImportNamedSpecifier {
272-
span: Span::new(start, maybe_as.span.hi()),
273+
span: Span::new_with_checked(start, maybe_as.span.hi()),
273274
local: maybe_as,
274275
imported: Some(ModuleExportName::Ident(orig_name)),
275276
is_type_only: false,
@@ -278,7 +279,7 @@ fn parse_import_specifier<'a, P: Parser<'a>>(
278279
} else {
279280
// `import { type as xxx } from 'mod'`
280281
return Ok(ImportSpecifier::Named(ImportNamedSpecifier {
281-
span: Span::new(start, orig_name.span.hi()),
282+
span: Span::new_with_checked(start, orig_name.span.hi()),
282283
local: maybe_as,
283284
imported: Some(ModuleExportName::Ident(orig_name)),
284285
is_type_only: false,
@@ -299,7 +300,7 @@ fn parse_import_specifier<'a, P: Parser<'a>>(
299300
if p.input_mut().eat(&P::Token::AS) {
300301
let local: Ident = parse_binding_ident(p, false)?.into();
301302
return Ok(ImportSpecifier::Named(ImportNamedSpecifier {
302-
span: Span::new(start, local.span.hi()),
303+
span: Span::new_with_checked(start, local.span.hi()),
303304
local,
304305
imported: Some(ModuleExportName::Ident(orig_name)),
305306
is_type_only,
@@ -326,7 +327,7 @@ fn parse_import_specifier<'a, P: Parser<'a>>(
326327
if p.input_mut().eat(&P::Token::AS) {
327328
let local: Ident = parse_binding_ident(p, false)?.into();
328329
Ok(ImportSpecifier::Named(ImportNamedSpecifier {
329-
span: Span::new(start, local.span.hi()),
330+
span: Span::new_with_checked(start, local.span.hi()),
330331
local,
331332
imported: Some(ModuleExportName::Str(orig_str)),
332333
is_type_only: false,

0 commit comments

Comments
 (0)