Skip to content

Commit abffc07

Browse files
authoredOct 17, 2024··
fix(es/parser): Correct > and < when exit type context (#9653)
**Related issue:** - Close #9471
1 parent 3ae87b5 commit abffc07

File tree

7 files changed

+90
-3
lines changed

7 files changed

+90
-3
lines changed
 

‎.changeset/fluffy-lizards-allow.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
swc_ecma_parser: patch
3+
swc_core: patch
4+
---
5+
6+
fix(es/parser): Correct `>` and `<` when exit type context
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const x0 = testNum as number > 0;
2+
const x1 = testNum as number >> 0;
3+
const x2 = testNum as number >= 0;
4+
const x3 = testNum as number >>> 0;
5+
const x4 = testNum as number < 0;
6+
const x5 = testNum as number << 0;
7+
const x6 = testNum as number <= 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var x0 = testNum > 0;
2+
var x1 = testNum >> 0;
3+
var x2 = testNum >= 0;
4+
var x3 = testNum >>> 0;
5+
var x4 = testNum < 0;
6+
var x5 = testNum << 0;
7+
var x6 = testNum <= 0;

‎crates/swc_ecma_parser/src/macros.rs

+15
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,30 @@ macro_rules! tok {
113113
("<<") => {
114114
crate::token::Token::BinOp(crate::token::BinOpToken::LShift)
115115
};
116+
("<=") => {
117+
crate::token::Token::BinOp(crate::token::BinOpToken::LtEq)
118+
};
119+
("<<=") => {
120+
crate::token::Token::AssignOp(crate::token::AssignOp::LShiftAssign)
121+
};
116122
('>') => {
117123
crate::token::Token::BinOp(crate::token::BinOpToken::Gt)
118124
};
119125
(">>") => {
120126
crate::token::Token::BinOp(crate::token::BinOpToken::RShift)
121127
};
128+
(">>>") => {
129+
crate::token::Token::BinOp(crate::token::BinOpToken::ZeroFillRShift)
130+
};
122131
(">=") => {
123132
crate::token::Token::BinOp(crate::token::BinOpToken::GtEq)
124133
};
134+
(">>=") => {
135+
crate::token::Token::AssignOp(crate::AssignOp::RShiftAssign)
136+
};
137+
(">>>=") => {
138+
crate::token::Token::AssignOp(crate::AssignOp::ZeroFillRShiftAssign)
139+
};
125140

126141
("++") => {
127142
crate::token::Token::PlusPlus

‎crates/swc_ecma_parser/src/parser/input.rs

+46
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,52 @@ impl<I: Tokens> Buffer<I> {
414414
});
415415
}
416416

417+
pub fn merge_lt_gt(&mut self) {
418+
debug_assert!(
419+
self.is(&tok!('<')) || self.is(&tok!('>')),
420+
"parser should only call merge_lt_gt when encountering '<' or '>' token"
421+
);
422+
423+
let span = self.cur_span();
424+
425+
if self.peek().is_none() {
426+
return;
427+
}
428+
429+
let next = self.next.as_ref().unwrap();
430+
431+
if span.hi != next.span.lo {
432+
return;
433+
}
434+
435+
let cur = self.cur.take().unwrap();
436+
let next = self.next.take().unwrap();
437+
438+
let token = match (&cur.token, &next.token) {
439+
(tok!('>'), tok!('>')) => tok!(">>"),
440+
(tok!('>'), tok!('=')) => tok!(">="),
441+
(tok!('>'), tok!(">>")) => tok!(">>>"),
442+
(tok!('>'), tok!(">=")) => tok!(">>="),
443+
(tok!('>'), tok!(">>=")) => tok!(">>>="),
444+
(tok!('<'), tok!('<')) => tok!("<<"),
445+
(tok!('<'), tok!('=')) => tok!("<="),
446+
(tok!('<'), tok!("<=")) => tok!("<<="),
447+
448+
_ => {
449+
self.cur = Some(cur);
450+
self.next = Some(next);
451+
return;
452+
}
453+
};
454+
let span = span.with_hi(next.span.hi);
455+
456+
self.cur = Some(TokenAndSpan {
457+
token,
458+
span,
459+
had_line_break: cur.had_line_break,
460+
});
461+
}
462+
417463
#[inline]
418464
pub fn is(&mut self, expected: &Token) -> bool {
419465
match self.cur() {

‎crates/swc_ecma_parser/src/parser/typescript.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -713,11 +713,17 @@ impl<I: Tokens> Parser<I> {
713713
pub(super) fn next_then_parse_ts_type(&mut self) -> PResult<Box<TsType>> {
714714
debug_assert!(self.input.syntax().typescript());
715715

716-
self.in_type().parse_with(|p| {
716+
let result = self.in_type().parse_with(|p| {
717717
bump!(p);
718718

719719
p.parse_ts_type()
720-
})
720+
});
721+
722+
if !self.ctx().in_type && is_one_of!(self, '>', '<') {
723+
self.input.merge_lt_gt();
724+
}
725+
726+
result
721727
}
722728

723729
/// `tsParseEnumMember`

‎crates/swc_ecma_parser/src/token.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{
99
use num_bigint::BigInt as BigIntValue;
1010
use swc_atoms::{atom, Atom, AtomStore};
1111
use swc_common::{Span, Spanned};
12-
use swc_ecma_ast::{AssignOp, BinaryOp};
12+
pub(crate) use swc_ecma_ast::{AssignOp, BinaryOp};
1313

1414
pub(crate) use self::{Keyword::*, Token::*};
1515
use crate::{error::Error, lexer::LexResult};

0 commit comments

Comments
 (0)
Please sign in to comment.