mirror of
https://github.com/swc-project/swc.git
synced 2024-12-28 08:04:43 +03:00
commit
bab2b73483
@ -22,7 +22,7 @@ impl Debug for BytePos {
|
||||
pub struct Span {
|
||||
/// Inclusive
|
||||
pub start: BytePos,
|
||||
/// Inclusive
|
||||
/// Exclusive
|
||||
pub end: BytePos,
|
||||
}
|
||||
impl Debug for Span {
|
||||
@ -30,7 +30,7 @@ impl Debug for Span {
|
||||
if self.start == BytePos(0) && self.end == BytePos(0) {
|
||||
write!(f, "_")
|
||||
} else {
|
||||
write!(f, "{}..{}", self.start, self.end.0 + 1)
|
||||
write!(f, "{}..{}", self.start, self.end)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,12 @@ impl<I: Input> LexerInput<I> {
|
||||
}
|
||||
|
||||
pub fn bump(&mut self) {
|
||||
let pos = self.cur
|
||||
.take()
|
||||
.unwrap_or_else(|| unreachable!("bump called on eof"))
|
||||
.0;
|
||||
let pos = match self.cur.take() {
|
||||
Some((p, prev_c)) => BytePos(p.0 + prev_c.len_utf8() as u32),
|
||||
None => unreachable!("bump is called without knowing current character"),
|
||||
};
|
||||
|
||||
self.cur = self.input.next();
|
||||
|
||||
self.last_pos = pos;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,9 @@ impl<I: Input> Lexer<I> {
|
||||
// e.g. `0` is decimal (so it can be part of float)
|
||||
//
|
||||
// e.g. `000` is octal
|
||||
if start != last_pos!() {
|
||||
if start.0 != last_pos!().0 - 1 {
|
||||
// `-1` is utf 8 length of `0`
|
||||
|
||||
return self.make_legacy_octal(start, 0f64);
|
||||
}
|
||||
} else {
|
||||
|
@ -25,7 +25,7 @@ impl SpanRange for usize {
|
||||
fn into_span(self) -> Span {
|
||||
Span {
|
||||
start: BytePos(self as _),
|
||||
end: BytePos(self as _),
|
||||
end: BytePos((self + 1usize) as _),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ impl SpanRange for Range<usize> {
|
||||
fn into_span(self) -> Span {
|
||||
Span {
|
||||
start: BytePos(self.start as _),
|
||||
end: BytePos((self.end - 1) as _),
|
||||
end: BytePos(self.end as _),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,7 +109,10 @@ fn test262_lexer_error_0001() {
|
||||
#[test]
|
||||
fn test262_lexer_error_0002() {
|
||||
assert_eq!(
|
||||
vec![Str("use strict".into(), false).span(0..15), Semi.span(15)],
|
||||
vec![
|
||||
Str("use strict".into(), false).span(0..15),
|
||||
Semi.span(15..16),
|
||||
],
|
||||
lex(r#"'use\x20strict';"#)
|
||||
);
|
||||
}
|
||||
@ -134,7 +137,7 @@ fn ident_escape_unicode() {
|
||||
|
||||
#[test]
|
||||
fn ident_escape_unicode_2() {
|
||||
assert_eq!(lex("℘℘"), vec!["℘℘".span(0..4)]);
|
||||
assert_eq!(lex("℘℘"), vec!["℘℘".span(0..6)]);
|
||||
|
||||
assert_eq!(lex(r#"℘\u2118"#), vec!["℘℘".span(0..9)]);
|
||||
}
|
||||
|
@ -85,20 +85,15 @@ macro_rules! token_including_semi {
|
||||
|
||||
/// This macro requires macro named 'last_pos' to be in scope.
|
||||
macro_rules! span {
|
||||
($p:expr, $start:expr) => {
|
||||
Span { start: $start, end: last_pos!($p), }
|
||||
};
|
||||
}
|
||||
|
||||
/// Takes `(parser, start)`, Returns |t| { Spanned::from }
|
||||
macro_rules! into_spanned {
|
||||
($p:expr, $start:expr) => {{
|
||||
|val| {
|
||||
let start = $start;
|
||||
let end = last_pos!($p);
|
||||
return ::swc_common::Spanned::from_unspanned(val, Span { start, end });
|
||||
let start: ::swc_common::BytePos = $start;
|
||||
let end: ::swc_common::BytePos = last_pos!($p);
|
||||
if cfg!(debug_assertions) && start > end {
|
||||
unreachable!("assertion failed: (span.start <= span.end).
|
||||
start = {}, end = {}", start, end)
|
||||
}
|
||||
}}
|
||||
Span { start, end }
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! spanned {
|
||||
@ -110,8 +105,12 @@ macro_rules! spanned {
|
||||
$($body)*
|
||||
};
|
||||
#[allow(unreachable_code)]
|
||||
{
|
||||
val.map(into_spanned!($p, start))
|
||||
match val {
|
||||
Ok(val) => {
|
||||
let end = last_pos!($p);
|
||||
Ok(::swc_common::Spanned::from_unspanned(val, Span { start, end }))
|
||||
},
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ impl<I: Input> Parser<I> {
|
||||
spanned!({
|
||||
assert_and_bump!('[');
|
||||
let mut elems = vec![];
|
||||
let mut comma = 0;
|
||||
let mut comma = 1;
|
||||
|
||||
while !eof!() && !is!(']') {
|
||||
if eat!(',') {
|
||||
@ -206,7 +206,11 @@ impl<I: Input> Parser<I> {
|
||||
continue;
|
||||
}
|
||||
|
||||
elems.extend(iter::repeat(None).take(comma));
|
||||
// Should have at least one comma between elements.
|
||||
if comma == 0 {
|
||||
expect!(',');
|
||||
}
|
||||
elems.extend(iter::repeat(None).take(comma - 1));
|
||||
comma = 0;
|
||||
elems.push(self.include_in_expr(true).parse_expr_or_spread().map(Some)?);
|
||||
}
|
||||
|
@ -83,7 +83,6 @@ impl<I: Input> Parser<I> {
|
||||
Keyword(Yield) if incl_yield => Ok(js_word!("yield")),
|
||||
Keyword(Await) if incl_await => Ok(js_word!("await")),
|
||||
Keyword(..) | Null | True | False => {
|
||||
println!("Word: {:?}", w);
|
||||
syntax_error!(SyntaxError::ExpectedIdent)
|
||||
}
|
||||
}
|
||||
|
@ -51,9 +51,13 @@ impl<I: Input> ParserInput<I> {
|
||||
|
||||
fn bump_inner(&mut self) -> Option<Token> {
|
||||
let prev = self.cur.take();
|
||||
self.last_pos = prev.as_ref()
|
||||
.map(|item| item.span.end)
|
||||
.unwrap_or(BytePos(0));
|
||||
self.last_pos = match prev {
|
||||
Some(Item {
|
||||
span: Span { end, .. },
|
||||
..
|
||||
}) => end,
|
||||
_ => self.last_pos,
|
||||
};
|
||||
|
||||
// If we have peeked a token, take it instead of calling lexer.next()
|
||||
self.cur = self.next.take().or_else(|| self.iter.next());
|
||||
|
Loading…
Reference in New Issue
Block a user