mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 10:12:42 +03:00
perf(common): Add more methods to Spanned
(#4749)
- Lots of code only needs `lo` or `hi`, but they call `span()`, which is inefficient in some cases. - This PR only adds a trivial amount of optimization. I may add full optimization in future. - This PR improves codegen performance of `ExprOrSpread` and `Option<ExprOrSpread>`.
This commit is contained in:
parent
6236e46574
commit
98df64517e
@ -12,16 +12,36 @@ pub use crate::syntax_pos::{
|
||||
pub trait Spanned {
|
||||
/// Get span of `self`.
|
||||
fn span(&self) -> Span;
|
||||
|
||||
#[inline]
|
||||
fn span_lo(&self) -> BytePos {
|
||||
self.span().lo
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_hi(&self) -> BytePos {
|
||||
self.span().hi
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Spanned for Cow<'a, T>
|
||||
where
|
||||
T: Spanned + Clone,
|
||||
{
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
(**self).span()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_lo(&self) -> BytePos {
|
||||
(**self).span_lo()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_hi(&self) -> BytePos {
|
||||
(**self).span_hi()
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for Span {
|
||||
@ -43,12 +63,29 @@ impl<S> Spanned for Option<S>
|
||||
where
|
||||
S: Spanned,
|
||||
{
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
Some(ref s) => s.span(),
|
||||
None => DUMMY_SP,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_lo(&self) -> BytePos {
|
||||
match *self {
|
||||
Some(ref s) => s.span_lo(),
|
||||
None => BytePos::DUMMY,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_hi(&self) -> BytePos {
|
||||
match *self {
|
||||
Some(ref s) => s.span_hi(),
|
||||
None => BytePos::DUMMY,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Spanned for Rc<S>
|
||||
@ -58,6 +95,16 @@ where
|
||||
fn span(&self) -> Span {
|
||||
<S as Spanned>::span(&*self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_lo(&self) -> BytePos {
|
||||
<S as Spanned>::span_lo(&*self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_hi(&self) -> BytePos {
|
||||
<S as Spanned>::span_hi(&*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Spanned for Arc<S>
|
||||
@ -67,6 +114,16 @@ where
|
||||
fn span(&self) -> Span {
|
||||
<S as Spanned>::span(&*self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_lo(&self) -> BytePos {
|
||||
<S as Spanned>::span_lo(&*self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_hi(&self) -> BytePos {
|
||||
<S as Spanned>::span_hi(&*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Spanned for Box<S>
|
||||
@ -76,6 +133,16 @@ where
|
||||
fn span(&self) -> Span {
|
||||
<S as Spanned>::span(&*self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_lo(&self) -> BytePos {
|
||||
<S as Spanned>::span_lo(&*self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_hi(&self) -> BytePos {
|
||||
<S as Spanned>::span_hi(&*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S> Spanned for &'a S
|
||||
@ -83,7 +150,17 @@ where
|
||||
S: ?Sized + Spanned,
|
||||
{
|
||||
fn span(&self) -> Span {
|
||||
<S as Spanned>::span(*self)
|
||||
<S as Spanned>::span(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_lo(&self) -> BytePos {
|
||||
<S as Spanned>::span_lo(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_hi(&self) -> BytePos {
|
||||
<S as Spanned>::span_hi(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,4 +175,18 @@ where
|
||||
::either::Either::Right(ref n) => n.span(),
|
||||
}
|
||||
}
|
||||
|
||||
fn span_lo(&self) -> BytePos {
|
||||
match *self {
|
||||
::either::Either::Left(ref n) => n.span_lo(),
|
||||
::either::Either::Right(ref n) => n.span_lo(),
|
||||
}
|
||||
}
|
||||
|
||||
fn span_hi(&self) -> BytePos {
|
||||
match *self {
|
||||
::either::Either::Left(ref n) => n.span_hi(),
|
||||
::either::Either::Right(ref n) => n.span_hi(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use is_macro::Is;
|
||||
use serde::{self, Deserialize, Serialize};
|
||||
use string_enum::StringEnum;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span, Spanned, DUMMY_SP};
|
||||
use swc_common::{ast_node, util::take::Take, BytePos, EqIgnoreSpan, Span, Spanned, DUMMY_SP};
|
||||
|
||||
use crate::{
|
||||
class::Class,
|
||||
@ -905,6 +905,7 @@ pub struct ExprOrSpread {
|
||||
}
|
||||
|
||||
impl Spanned for ExprOrSpread {
|
||||
#[inline]
|
||||
fn span(&self) -> Span {
|
||||
let expr = self.expr.span();
|
||||
match self.spread {
|
||||
@ -912,6 +913,19 @@ impl Spanned for ExprOrSpread {
|
||||
None => expr,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_lo(&self) -> BytePos {
|
||||
match self.spread {
|
||||
Some(s) => s.lo,
|
||||
None => self.expr.span_lo(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn span_hi(&self) -> BytePos {
|
||||
self.expr.span_hi()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Expr> for ExprOrSpread {
|
||||
|
@ -67,6 +67,10 @@ where
|
||||
}
|
||||
|
||||
pub(super) fn emit_leading_comments(&mut self, mut pos: BytePos, is_hi: bool) -> Result {
|
||||
if pos.is_dummy() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let comments = match self.comments {
|
||||
Some(ref comments) => comments,
|
||||
None => return Ok(()),
|
||||
@ -79,11 +83,8 @@ where
|
||||
write_comments!(self, false, comments.take_leading(pos))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn emit_leading_comments_of_span(&mut self, span: Span, is_hi: bool) -> Result {
|
||||
if span.is_dummy_ignoring_cmt() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let pos = if is_hi { span.hi } else { span.lo };
|
||||
self.emit_leading_comments(pos, is_hi)
|
||||
}
|
||||
|
@ -2172,7 +2172,7 @@ where
|
||||
&& previous_sibling.hi != parent_node.hi()
|
||||
&& self.comments.is_some()
|
||||
{
|
||||
self.emit_leading_comments(previous_sibling.span().hi(), true)?;
|
||||
self.emit_leading_comments(previous_sibling.hi(), true)?;
|
||||
}
|
||||
|
||||
self.write_delim(format)?;
|
||||
@ -2270,11 +2270,11 @@ where
|
||||
|
||||
if let Some(previous_sibling) = previous_sibling {
|
||||
if format.contains(ListFormat::DelimitersMask)
|
||||
&& previous_sibling.span().hi() != parent_node.hi()
|
||||
&& previous_sibling.hi() != parent_node.hi()
|
||||
&& emit_trailing_comments
|
||||
&& self.comments.is_some()
|
||||
{
|
||||
self.emit_leading_comments(previous_sibling.span().hi(), true)?;
|
||||
self.emit_leading_comments(previous_sibling.hi(), true)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3574,7 +3574,7 @@ fn is_space_require_before_rhs(rhs: &Expr) -> bool {
|
||||
}
|
||||
|
||||
fn is_empty_comments(span: &Span, comments: &Option<&dyn Comments>) -> bool {
|
||||
span.is_dummy() || comments.map_or(true, |c| !c.has_leading(span.hi() - BytePos(1)))
|
||||
span.is_dummy() || comments.map_or(true, |c| !c.has_leading(span.span_hi() - BytePos(1)))
|
||||
}
|
||||
|
||||
fn minify_number(num: f64) -> String {
|
||||
|
@ -105,13 +105,13 @@ macro_rules! semi {
|
||||
/// - `srcmap!(false)` for end (span.hi)
|
||||
macro_rules! srcmap {
|
||||
($emitter:expr, $n:expr, true) => {{
|
||||
let bp = $n.span().lo;
|
||||
if !bp.is_dummy() {
|
||||
$emitter.wr.add_srcmap(bp)?;
|
||||
let lo = $n.span_lo();
|
||||
if !lo.is_dummy() {
|
||||
$emitter.wr.add_srcmap(lo)?;
|
||||
}
|
||||
}};
|
||||
($emitter:expr, $n:expr, false) => {
|
||||
let hi = $n.span().hi;
|
||||
let hi = $n.span_hi();
|
||||
if !hi.is_dummy() {
|
||||
$emitter.wr.add_srcmap(hi)?;
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ impl<I: Tokens> Parser<I> {
|
||||
|
||||
let args = self.parse_args(false)?;
|
||||
Ok(Box::new(Expr::Call(CallExpr {
|
||||
span: span!(self, expr.span().lo()),
|
||||
span: span!(self, expr.span_lo()),
|
||||
callee: Callee::Expr(expr),
|
||||
args,
|
||||
type_args: None,
|
||||
|
@ -19,7 +19,7 @@ impl<I: Tokens> Parser<I> {
|
||||
let _tracing = debug_tracing!(self, "parse_expr");
|
||||
|
||||
let expr = self.parse_assignment_expr()?;
|
||||
let start = expr.span().lo();
|
||||
let start = expr.span_lo();
|
||||
|
||||
if is!(self, ',') {
|
||||
let mut exprs = vec![expr];
|
||||
@ -217,7 +217,7 @@ impl<I: Tokens> Parser<I> {
|
||||
..self.ctx()
|
||||
};
|
||||
let alt = self.with_ctx(ctx).parse_assignment_expr()?;
|
||||
let span = Span::new(start, alt.span().hi(), Default::default());
|
||||
let span = Span::new(start, alt.span_hi(), Default::default());
|
||||
Ok(Box::new(Expr::Cond(CondExpr {
|
||||
span,
|
||||
test,
|
||||
@ -915,8 +915,8 @@ impl<I: Tokens> Parser<I> {
|
||||
// span of sequence expression should not include '(', ')'
|
||||
let seq_expr = Box::new(Expr::Seq(SeqExpr {
|
||||
span: Span::new(
|
||||
exprs.first().unwrap().span().lo(),
|
||||
exprs.last().unwrap().span().hi(),
|
||||
exprs.first().unwrap().span_lo(),
|
||||
exprs.last().unwrap().span_hi(),
|
||||
Default::default(),
|
||||
),
|
||||
exprs,
|
||||
@ -957,7 +957,7 @@ impl<I: Tokens> Parser<I> {
|
||||
tag: Box<Expr>,
|
||||
type_params: Option<TsTypeParamInstantiation>,
|
||||
) -> PResult<TaggedTpl> {
|
||||
let tagged_tpl_start = tag.span().lo();
|
||||
let tagged_tpl_start = tag.span_lo();
|
||||
trace_cur!(self, parse_tagged_tpl);
|
||||
|
||||
let tpl = self.parse_tpl(true)?;
|
||||
@ -1168,8 +1168,8 @@ impl<I: Tokens> Parser<I> {
|
||||
let bracket_lo = self.input.prev_span().lo;
|
||||
let prop = self.include_in_expr(true).parse_expr()?;
|
||||
expect!(self, ']');
|
||||
let span = Span::new(obj.span().lo(), self.input.last_pos(), Default::default());
|
||||
debug_assert_eq!(obj.span().lo(), span.lo());
|
||||
let span = Span::new(obj.span_lo(), self.input.last_pos(), Default::default());
|
||||
debug_assert_eq!(obj.span_lo(), span.lo());
|
||||
let prop = ComputedPropName {
|
||||
span: Span::new(bracket_lo, self.input.last_pos(), Default::default()),
|
||||
expr: prop,
|
||||
@ -1290,9 +1290,9 @@ impl<I: Tokens> Parser<I> {
|
||||
Either::Left(p) => MemberProp::PrivateName(p),
|
||||
Either::Right(i) => MemberProp::Ident(i),
|
||||
})?;
|
||||
let span = span!(self, obj.span().lo());
|
||||
debug_assert_eq!(obj.span().lo(), span.lo());
|
||||
debug_assert_eq!(prop.span().hi(), span.hi());
|
||||
let span = span!(self, obj.span_lo());
|
||||
debug_assert_eq!(obj.span_lo(), span.lo());
|
||||
debug_assert_eq!(prop.span_hi(), span.hi());
|
||||
|
||||
let type_args = if self.syntax().typescript() && is!(self, '<') {
|
||||
self.try_parse_ts_type_args()
|
||||
@ -1631,7 +1631,7 @@ impl<I: Tokens> Parser<I> {
|
||||
arg = ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Cond(CondExpr {
|
||||
span: Span::new(start, alt.span().hi(), Default::default()),
|
||||
span: Span::new(start, alt.span_hi(), Default::default()),
|
||||
|
||||
test,
|
||||
cons,
|
||||
@ -1838,7 +1838,7 @@ impl<I: Tokens> Parser<I> {
|
||||
fn at_possible_async(&mut self, expr: &Expr) -> PResult<bool> {
|
||||
// TODO(kdy1): !this.state.containsEsc &&
|
||||
|
||||
Ok(self.state.potential_arrow_start == Some(expr.span().lo())
|
||||
Ok(self.state.potential_arrow_start == Some(expr.span_lo())
|
||||
&& matches!(
|
||||
*expr,
|
||||
Expr::Ident(Ident {
|
||||
|
@ -93,7 +93,7 @@ impl<I: Tokens> Parser<I> {
|
||||
&& !self.input.had_line_break_before_cur()
|
||||
&& is!(self, "as")
|
||||
{
|
||||
let start = left.span().lo();
|
||||
let start = left.span_lo();
|
||||
let expr = left;
|
||||
let node = if peeked_is!(self, "const") {
|
||||
bump!(self); // as
|
||||
@ -212,7 +212,7 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
|
||||
let node = Box::new(Expr::Bin(BinExpr {
|
||||
span: Span::new(left.span().lo(), right.span().hi(), Default::default()),
|
||||
span: Span::new(left.span_lo(), right.span_hi(), Default::default()),
|
||||
op,
|
||||
left,
|
||||
right,
|
||||
@ -253,7 +253,7 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
|
||||
let arg = self.parse_unary_expr()?;
|
||||
let span = Span::new(start, arg.span().hi(), Default::default());
|
||||
let span = Span::new(start, arg.span_hi(), Default::default());
|
||||
self.check_assign_target(&arg, false);
|
||||
|
||||
return Ok(Box::new(Expr::Update(UpdateExpr {
|
||||
@ -311,7 +311,7 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
|
||||
return Ok(Box::new(Expr::Unary(UnaryExpr {
|
||||
span: Span::new(start, arg.span().hi(), Default::default()),
|
||||
span: Span::new(start, arg.span_hi(), Default::default()),
|
||||
op,
|
||||
arg,
|
||||
})));
|
||||
@ -344,7 +344,7 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
|
||||
return Ok(Box::new(Expr::Update(UpdateExpr {
|
||||
span: span!(self, expr.span().lo()),
|
||||
span: span!(self, expr.span_lo()),
|
||||
prefix: false,
|
||||
op,
|
||||
arg: expr,
|
||||
|
@ -2149,14 +2149,14 @@ impl<I: Tokens> Parser<I> {
|
||||
while !self.input.had_line_break_before_cur() && eat!(self, '[') {
|
||||
if eat!(self, ']') {
|
||||
ty = Box::new(TsType::TsArrayType(TsArrayType {
|
||||
span: span!(self, ty.span().lo()),
|
||||
span: span!(self, ty.span_lo()),
|
||||
elem_type: ty,
|
||||
}));
|
||||
} else {
|
||||
let index_type = self.parse_ts_type()?;
|
||||
expect!(self, ']');
|
||||
ty = Box::new(TsType::TsIndexedAccessType(TsIndexedAccessType {
|
||||
span: span!(self, ty.span().lo()),
|
||||
span: span!(self, ty.span_lo()),
|
||||
readonly,
|
||||
obj_type: ty,
|
||||
index_type,
|
||||
@ -2259,7 +2259,7 @@ impl<I: Tokens> Parser<I> {
|
||||
return Ok(Default::default());
|
||||
}
|
||||
|
||||
let start = expr.span().lo();
|
||||
let start = expr.span_lo();
|
||||
|
||||
match &*expr.sym {
|
||||
"declare" => {
|
||||
|
Loading…
Reference in New Issue
Block a user