Handle escapes in jsx attributes. Fix #299.

This commit is contained in:
강동윤 2019-03-01 16:31:26 +09:00
parent 99e34ddbbd
commit a2144bbbf5
2 changed files with 112 additions and 2 deletions

View File

@ -144,7 +144,7 @@ impl<'a, I: Input> Lexer<'a, I> {
debug_assert!(self.syntax.jsx());
self.input.bump(); // `quote`
let mut has_escape = false;
let mut out = String::new();
let mut chunk_start = self.input.cur_pos();
loop {
@ -158,6 +158,14 @@ impl<'a, I: Input> Lexer<'a, I> {
let cur_pos = self.input.cur_pos();
if ch == '\\' {
has_escape = true;
out.push_str(self.input.slice(chunk_start, cur_pos));
out.extend(self.read_escaped_char(&mut Raw(None))?);
chunk_start = self.input.cur_pos();
continue;
}
if ch == quote {
break;
}
@ -181,7 +189,7 @@ impl<'a, I: Input> Lexer<'a, I> {
self.input.bump();
return Ok(Token::Str {
value: out.into(),
has_escape: false,
has_escape,
});
}

View File

@ -960,6 +960,108 @@ fn jsx_05() {
);
}
#[test]
fn issue_299_01() {
assert_eq!(
lex_tokens(
::Syntax::Es(::EsConfig {
jsx: true,
..Default::default()
}),
"<Page num='\\ '>ABC</Page>;"
),
vec![
Token::JSXTagStart,
Token::JSXName {
name: "Page".into()
},
Token::JSXName { name: "num".into() },
tok!('='),
Token::Str {
value: " ".into(),
has_escape: true
},
Token::JSXTagEnd,
JSXText { raw: "ABC".into() },
JSXTagStart,
tok!('/'),
JSXName {
name: "Page".into()
},
JSXTagEnd,
Semi,
]
);
}
#[test]
fn issue_299_02() {
assert_eq!(
lex_tokens(
::Syntax::Es(::EsConfig {
jsx: true,
..Default::default()
}),
"<Page num='\\''>ABC</Page>;"
),
vec![
Token::JSXTagStart,
Token::JSXName {
name: "Page".into()
},
Token::JSXName { name: "num".into() },
tok!('='),
Token::Str {
value: "'".into(),
has_escape: true
},
Token::JSXTagEnd,
JSXText { raw: "ABC".into() },
JSXTagStart,
tok!('/'),
JSXName {
name: "Page".into()
},
JSXTagEnd,
Semi,
]
);
}
#[test]
fn issue_299_03() {
assert_eq!(
lex_tokens(
::Syntax::Es(::EsConfig {
jsx: true,
..Default::default()
}),
"<Page num='\\\\'>ABC</Page>;"
),
vec![
Token::JSXTagStart,
Token::JSXName {
name: "Page".into()
},
Token::JSXName { name: "num".into() },
tok!('='),
Token::Str {
value: "\\".into(),
has_escape: true
},
Token::JSXTagEnd,
JSXText { raw: "ABC".into() },
JSXTagStart,
tok!('/'),
JSXName {
name: "Page".into()
},
JSXTagEnd,
Semi,
]
);
}
#[bench]
fn lex_colors_js(b: &mut Bencher) {
b.bytes = include_str!("../../colors.js").len() as _;