mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 21:54:36 +03:00
fix(es/parser, es/compat): transform tagged template with invalid escape sequence (#2939)
swc_ecma_parser: - Preserve more data for invalid escapes in template literals. swc_ecma_transforms_compat: - Fix handling of template literals. (Closes #2674)
This commit is contained in:
parent
a93f1111f9
commit
d8c8641e59
@ -1,3 +1,3 @@
|
|||||||
var x_y = () => String.raw;
|
console.log(({
|
||||||
console.log(x_y()`\4321\u\x`);
|
y: ()=>String.raw
|
||||||
console.log(String.raw`\4321\u\x`);
|
}).y()`\4321\u\x`), console.log(String.raw`\4321\u\x`);
|
||||||
|
@ -972,7 +972,7 @@ impl<'a, I: Input> Lexer<'a, I> {
|
|||||||
|
|
||||||
// TODO: Optimize
|
// TODO: Optimize
|
||||||
let mut has_escape = false;
|
let mut has_escape = false;
|
||||||
let mut cooked = Some(String::new());
|
let mut cooked = Ok(String::new());
|
||||||
let mut raw = String::new();
|
let mut raw = String::new();
|
||||||
|
|
||||||
while let Some(c) = self.cur() {
|
while let Some(c) = self.cur() {
|
||||||
@ -1002,17 +1002,13 @@ impl<'a, I: Input> Lexer<'a, I> {
|
|||||||
let mut wrapped = Raw(Some(raw));
|
let mut wrapped = Raw(Some(raw));
|
||||||
match self.read_escaped_char(&mut wrapped) {
|
match self.read_escaped_char(&mut wrapped) {
|
||||||
Ok(Some(s)) => {
|
Ok(Some(s)) => {
|
||||||
if let Some(ref mut cooked) = cooked {
|
if let Ok(ref mut cooked) = cooked {
|
||||||
cooked.extend(s);
|
cooked.extend(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
if self.target < EsVersion::Es2018 {
|
cooked = Err(error);
|
||||||
return Err(error);
|
|
||||||
} else {
|
|
||||||
cooked = None;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
raw = wrapped.0.unwrap();
|
raw = wrapped.0.unwrap();
|
||||||
@ -1032,13 +1028,13 @@ impl<'a, I: Input> Lexer<'a, I> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.bump();
|
self.bump();
|
||||||
if let Some(ref mut cooked) = cooked {
|
if let Ok(ref mut cooked) = cooked {
|
||||||
cooked.push(c);
|
cooked.push(c);
|
||||||
}
|
}
|
||||||
raw.push(c);
|
raw.push(c);
|
||||||
} else {
|
} else {
|
||||||
self.bump();
|
self.bump();
|
||||||
if let Some(ref mut cooked) = cooked {
|
if let Ok(ref mut cooked) = cooked {
|
||||||
cooked.push(c);
|
cooked.push(c);
|
||||||
}
|
}
|
||||||
raw.push(c);
|
raw.push(c);
|
||||||
|
@ -722,15 +722,6 @@ pub(crate) fn lex_tokens(syntax: Syntax, s: &'static str) -> Vec<Token> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) fn lex_tokens_with_target(
|
|
||||||
syntax: Syntax,
|
|
||||||
target: EsVersion,
|
|
||||||
s: &'static str,
|
|
||||||
) -> Vec<Token> {
|
|
||||||
with_lexer(syntax, target, s, |l| Ok(l.map(|ts| ts.token).collect())).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `(tokens, recovered_errors)`. `(tokens)` may contain an error token
|
/// Returns `(tokens, recovered_errors)`. `(tokens)` may contain an error token
|
||||||
/// if the lexer fails to recover from it.
|
/// if the lexer fails to recover from it.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
state::{lex, lex_module_errors, lex_tokens, lex_tokens_with_target, with_lexer},
|
state::{lex, lex_module_errors, lex_tokens, with_lexer},
|
||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -9,7 +9,7 @@ use crate::{
|
|||||||
lexer::state::lex_errors,
|
lexer::state::lex_errors,
|
||||||
};
|
};
|
||||||
use std::{ops::Range, str};
|
use std::{ops::Range, str};
|
||||||
use swc_ecma_ast::EsVersion;
|
use swc_common::SyntaxContext;
|
||||||
use test::{black_box, Bencher};
|
use test::{black_box, Bencher};
|
||||||
|
|
||||||
fn sp(r: Range<usize>) -> Span {
|
fn sp(r: Range<usize>) -> Span {
|
||||||
@ -231,7 +231,7 @@ multiline`"
|
|||||||
vec![
|
vec![
|
||||||
tok!('`'),
|
tok!('`'),
|
||||||
Token::Template {
|
Token::Template {
|
||||||
cooked: Some("this\nis\nmultiline".into()),
|
cooked: Ok("this\nis\nmultiline".into()),
|
||||||
raw: "this\nis\nmultiline".into(),
|
raw: "this\nis\nmultiline".into(),
|
||||||
has_escape: false
|
has_escape: false
|
||||||
},
|
},
|
||||||
@ -247,7 +247,7 @@ fn tpl_raw_unicode_escape() {
|
|||||||
vec![
|
vec![
|
||||||
tok!('`'),
|
tok!('`'),
|
||||||
Token::Template {
|
Token::Template {
|
||||||
cooked: Some(format!("{}", '\u{0010}').into()),
|
cooked: Ok(format!("{}", '\u{0010}').into()),
|
||||||
raw: "\\u{0010}".into(),
|
raw: "\\u{0010}".into(),
|
||||||
has_escape: true
|
has_escape: true
|
||||||
},
|
},
|
||||||
@ -259,11 +259,20 @@ fn tpl_raw_unicode_escape() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn tpl_invalid_unicode_escape() {
|
fn tpl_invalid_unicode_escape() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lex_tokens_with_target(Syntax::default(), EsVersion::Es2018, r"`\unicode`"),
|
lex_tokens(Syntax::default(), r"`\unicode`"),
|
||||||
vec![
|
vec![
|
||||||
tok!('`'),
|
tok!('`'),
|
||||||
Token::Template {
|
Token::Template {
|
||||||
cooked: None,
|
cooked: Err(Error {
|
||||||
|
error: Box::new((
|
||||||
|
Span {
|
||||||
|
lo: BytePos(1),
|
||||||
|
hi: BytePos(3),
|
||||||
|
ctxt: SyntaxContext::empty()
|
||||||
|
},
|
||||||
|
SyntaxError::ExpectedHexChars { count: 4 }
|
||||||
|
))
|
||||||
|
}),
|
||||||
raw: "\\unicode".into(),
|
raw: "\\unicode".into(),
|
||||||
has_escape: true
|
has_escape: true
|
||||||
},
|
},
|
||||||
@ -271,20 +280,47 @@ fn tpl_invalid_unicode_escape() {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lex_tokens_with_target(Syntax::default(), EsVersion::Es2017, r"`\unicode`"),
|
lex_tokens(Syntax::default(), r"`\u{`"),
|
||||||
vec![
|
vec![
|
||||||
tok!('`'),
|
tok!('`'),
|
||||||
Token::Error(Error {
|
|
||||||
error: Box::new((sp(1..3), SyntaxError::ExpectedHexChars { count: 4 })),
|
|
||||||
}),
|
|
||||||
Token::Template {
|
Token::Template {
|
||||||
cooked: Some("nicode".into()),
|
cooked: Err(Error {
|
||||||
raw: "nicode".into(),
|
error: Box::new((
|
||||||
has_escape: false,
|
Span {
|
||||||
|
lo: BytePos(4),
|
||||||
|
hi: BytePos(4),
|
||||||
|
ctxt: SyntaxContext::empty()
|
||||||
|
},
|
||||||
|
SyntaxError::InvalidCodePoint
|
||||||
|
))
|
||||||
|
}),
|
||||||
|
raw: "\\u{".into(),
|
||||||
|
has_escape: true
|
||||||
},
|
},
|
||||||
tok!('`')
|
tok!('`'),
|
||||||
]
|
]
|
||||||
)
|
);
|
||||||
|
assert_eq!(
|
||||||
|
lex_tokens(Syntax::default(), r"`\xhex`"),
|
||||||
|
vec![
|
||||||
|
tok!('`'),
|
||||||
|
Token::Template {
|
||||||
|
cooked: Err(Error {
|
||||||
|
error: Box::new((
|
||||||
|
Span {
|
||||||
|
lo: BytePos(1),
|
||||||
|
hi: BytePos(3),
|
||||||
|
ctxt: SyntaxContext::empty()
|
||||||
|
},
|
||||||
|
SyntaxError::ExpectedHexChars { count: 2 }
|
||||||
|
))
|
||||||
|
}),
|
||||||
|
raw: "\\xhex".into(),
|
||||||
|
has_escape: true
|
||||||
|
},
|
||||||
|
tok!('`'),
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -687,7 +723,7 @@ fn tpl_empty() {
|
|||||||
tok!('`'),
|
tok!('`'),
|
||||||
Template {
|
Template {
|
||||||
raw: "".into(),
|
raw: "".into(),
|
||||||
cooked: Some("".into()),
|
cooked: Ok("".into()),
|
||||||
has_escape: false
|
has_escape: false
|
||||||
},
|
},
|
||||||
tok!('`')
|
tok!('`')
|
||||||
@ -703,7 +739,7 @@ fn tpl() {
|
|||||||
tok!('`'),
|
tok!('`'),
|
||||||
Template {
|
Template {
|
||||||
raw: "".into(),
|
raw: "".into(),
|
||||||
cooked: Some("".into()),
|
cooked: Ok("".into()),
|
||||||
has_escape: false
|
has_escape: false
|
||||||
},
|
},
|
||||||
tok!("${"),
|
tok!("${"),
|
||||||
@ -711,7 +747,7 @@ fn tpl() {
|
|||||||
tok!('}'),
|
tok!('}'),
|
||||||
Template {
|
Template {
|
||||||
raw: "".into(),
|
raw: "".into(),
|
||||||
cooked: Some("".into()),
|
cooked: Ok("".into()),
|
||||||
has_escape: false
|
has_escape: false
|
||||||
},
|
},
|
||||||
tok!('`'),
|
tok!('`'),
|
||||||
@ -880,7 +916,7 @@ fn issue_191() {
|
|||||||
tok!('`'),
|
tok!('`'),
|
||||||
Token::Template {
|
Token::Template {
|
||||||
raw: "".into(),
|
raw: "".into(),
|
||||||
cooked: Some("".into()),
|
cooked: Ok("".into()),
|
||||||
has_escape: false,
|
has_escape: false,
|
||||||
},
|
},
|
||||||
tok!("${"),
|
tok!("${"),
|
||||||
@ -888,7 +924,7 @@ fn issue_191() {
|
|||||||
tok!('}'),
|
tok!('}'),
|
||||||
Token::Template {
|
Token::Template {
|
||||||
raw: "<bar>".into(),
|
raw: "<bar>".into(),
|
||||||
cooked: Some("<bar>".into()),
|
cooked: Ok("<bar>".into()),
|
||||||
has_escape: false,
|
has_escape: false,
|
||||||
},
|
},
|
||||||
tok!('`')
|
tok!('`')
|
||||||
|
@ -332,7 +332,7 @@ impl<'a, I: Tokens> Parser<I> {
|
|||||||
|
|
||||||
tok!('`') => {
|
tok!('`') => {
|
||||||
// parse template literal
|
// parse template literal
|
||||||
return Ok(Box::new(Expr::Tpl(self.parse_tpl()?)));
|
return Ok(Box::new(Expr::Tpl(self.parse_tpl(false)?)));
|
||||||
}
|
}
|
||||||
|
|
||||||
tok!('(') => {
|
tok!('(') => {
|
||||||
@ -847,12 +847,15 @@ impl<'a, I: Tokens> Parser<I> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::vec_box)]
|
#[allow(clippy::vec_box)]
|
||||||
fn parse_tpl_elements(&mut self) -> PResult<(Vec<Box<Expr>>, Vec<TplElement>)> {
|
fn parse_tpl_elements(
|
||||||
|
&mut self,
|
||||||
|
is_tagged_tpl: bool,
|
||||||
|
) -> PResult<(Vec<Box<Expr>>, Vec<TplElement>)> {
|
||||||
trace_cur!(self, parse_tpl_elements);
|
trace_cur!(self, parse_tpl_elements);
|
||||||
|
|
||||||
let mut exprs = vec![];
|
let mut exprs = vec![];
|
||||||
|
|
||||||
let cur_elem = self.parse_tpl_element()?;
|
let cur_elem = self.parse_tpl_element(is_tagged_tpl)?;
|
||||||
let mut is_tail = cur_elem.tail;
|
let mut is_tail = cur_elem.tail;
|
||||||
let mut quasis = vec![cur_elem];
|
let mut quasis = vec![cur_elem];
|
||||||
|
|
||||||
@ -860,7 +863,7 @@ impl<'a, I: Tokens> Parser<I> {
|
|||||||
expect!(self, "${");
|
expect!(self, "${");
|
||||||
exprs.push(self.include_in_expr(true).parse_expr()?);
|
exprs.push(self.include_in_expr(true).parse_expr()?);
|
||||||
expect!(self, '}');
|
expect!(self, '}');
|
||||||
let elem = self.parse_tpl_element()?;
|
let elem = self.parse_tpl_element(is_tagged_tpl)?;
|
||||||
is_tail = elem.tail;
|
is_tail = elem.tail;
|
||||||
quasis.push(elem);
|
quasis.push(elem);
|
||||||
}
|
}
|
||||||
@ -876,7 +879,7 @@ impl<'a, I: Tokens> Parser<I> {
|
|||||||
let tagged_tpl_start = tag.span().lo();
|
let tagged_tpl_start = tag.span().lo();
|
||||||
trace_cur!(self, parse_tagged_tpl);
|
trace_cur!(self, parse_tagged_tpl);
|
||||||
|
|
||||||
let tpl = self.parse_tpl()?;
|
let tpl = self.parse_tpl(true)?;
|
||||||
|
|
||||||
let span = span!(self, tagged_tpl_start);
|
let span = span!(self, tagged_tpl_start);
|
||||||
Ok(TaggedTpl {
|
Ok(TaggedTpl {
|
||||||
@ -887,13 +890,13 @@ impl<'a, I: Tokens> Parser<I> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn parse_tpl(&mut self) -> PResult<Tpl> {
|
pub(super) fn parse_tpl(&mut self, is_tagged_tpl: bool) -> PResult<Tpl> {
|
||||||
trace_cur!(self, parse_tpl);
|
trace_cur!(self, parse_tpl);
|
||||||
let start = cur_pos!(self);
|
let start = cur_pos!(self);
|
||||||
|
|
||||||
assert_and_bump!(self, '`');
|
assert_and_bump!(self, '`');
|
||||||
|
|
||||||
let (exprs, quasis) = self.parse_tpl_elements()?;
|
let (exprs, quasis) = self.parse_tpl_elements(is_tagged_tpl)?;
|
||||||
|
|
||||||
expect!(self, '`');
|
expect!(self, '`');
|
||||||
|
|
||||||
@ -905,7 +908,7 @@ impl<'a, I: Tokens> Parser<I> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn parse_tpl_element(&mut self) -> PResult<TplElement> {
|
pub(super) fn parse_tpl_element(&mut self, is_tagged_tpl: bool) -> PResult<TplElement> {
|
||||||
let start = cur_pos!(self);
|
let start = cur_pos!(self);
|
||||||
|
|
||||||
let (raw, cooked) = match *cur!(self, true)? {
|
let (raw, cooked) = match *cur!(self, true)? {
|
||||||
@ -914,24 +917,43 @@ impl<'a, I: Tokens> Parser<I> {
|
|||||||
raw,
|
raw,
|
||||||
cooked,
|
cooked,
|
||||||
has_escape,
|
has_escape,
|
||||||
} => (
|
} => match cooked {
|
||||||
Str {
|
Ok(cooked) => (
|
||||||
span: span!(self, start),
|
Str {
|
||||||
value: raw,
|
span: span!(self, start),
|
||||||
has_escape,
|
value: raw,
|
||||||
kind: StrKind::Normal {
|
has_escape,
|
||||||
contains_quote: false,
|
kind: StrKind::Normal {
|
||||||
|
contains_quote: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
Some(Str {
|
||||||
cooked.map(|cooked| Str {
|
span: span!(self, start),
|
||||||
span: span!(self, start),
|
value: cooked,
|
||||||
value: cooked,
|
has_escape,
|
||||||
has_escape,
|
kind: StrKind::Normal {
|
||||||
kind: StrKind::Normal {
|
contains_quote: false,
|
||||||
contains_quote: false,
|
},
|
||||||
},
|
}),
|
||||||
}),
|
),
|
||||||
),
|
Err(err) => {
|
||||||
|
if is_tagged_tpl {
|
||||||
|
(
|
||||||
|
Str {
|
||||||
|
span: span!(self, start),
|
||||||
|
value: raw,
|
||||||
|
has_escape,
|
||||||
|
kind: StrKind::Normal {
|
||||||
|
contains_quote: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
_ => unexpected!(self, "template token"),
|
_ => unexpected!(self, "template token"),
|
||||||
|
@ -1771,7 +1771,7 @@ impl<I: Tokens> Parser<I> {
|
|||||||
|
|
||||||
let mut types = vec![];
|
let mut types = vec![];
|
||||||
|
|
||||||
let cur_elem = self.parse_tpl_element()?;
|
let cur_elem = self.parse_tpl_element(false)?;
|
||||||
let mut is_tail = cur_elem.tail;
|
let mut is_tail = cur_elem.tail;
|
||||||
let mut quasis = vec![cur_elem];
|
let mut quasis = vec![cur_elem];
|
||||||
|
|
||||||
@ -1779,7 +1779,7 @@ impl<I: Tokens> Parser<I> {
|
|||||||
expect!(self, "${");
|
expect!(self, "${");
|
||||||
types.push(self.parse_ts_type()?);
|
types.push(self.parse_ts_type()?);
|
||||||
expect!(self, '}');
|
expect!(self, '}');
|
||||||
let elem = self.parse_tpl_element()?;
|
let elem = self.parse_tpl_element(false)?;
|
||||||
is_tail = elem.tail;
|
is_tail = elem.tail;
|
||||||
quasis.push(elem);
|
quasis.push(elem);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! [babel/babylon]:https://github.com/babel/babel/blob/2d378d076eb0c5fe63234a8b509886005c01d7ee/packages/babylon/src/tokenizer/types.js
|
//! [babel/babylon]:https://github.com/babel/babel/blob/2d378d076eb0c5fe63234a8b509886005c01d7ee/packages/babylon/src/tokenizer/types.js
|
||||||
pub(crate) use self::{AssignOpToken::*, BinOpToken::*, Keyword::*, Token::*};
|
pub(crate) use self::{AssignOpToken::*, BinOpToken::*, Keyword::*, Token::*};
|
||||||
use crate::error::Error;
|
use crate::{error::Error, lexer::LexResult};
|
||||||
use enum_kind::Kind;
|
use enum_kind::Kind;
|
||||||
use num_bigint::BigInt as BigIntValue;
|
use num_bigint::BigInt as BigIntValue;
|
||||||
use std::{
|
use std::{
|
||||||
@ -70,7 +70,7 @@ pub enum Token {
|
|||||||
BackQuote,
|
BackQuote,
|
||||||
Template {
|
Template {
|
||||||
raw: JsWord,
|
raw: JsWord,
|
||||||
cooked: Option<JsWord>,
|
cooked: LexResult<JsWord>,
|
||||||
has_escape: bool,
|
has_escape: bool,
|
||||||
},
|
},
|
||||||
/// ':'
|
/// ':'
|
||||||
|
@ -6,7 +6,7 @@ use swc_ecma_ast::*;
|
|||||||
use swc_ecma_transforms_base::{helper, perf::Parallel};
|
use swc_ecma_transforms_base::{helper, perf::Parallel};
|
||||||
use swc_ecma_transforms_macros::parallel;
|
use swc_ecma_transforms_macros::parallel;
|
||||||
use swc_ecma_utils::{
|
use swc_ecma_utils::{
|
||||||
is_literal, prepend_stmts, private_ident, quote_ident, ExprFactory, StmtLike,
|
is_literal, prepend_stmts, private_ident, quote_ident, undefined, ExprFactory, StmtLike,
|
||||||
};
|
};
|
||||||
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};
|
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};
|
||||||
|
|
||||||
@ -64,10 +64,7 @@ impl VisitMut for TemplateLiteral {
|
|||||||
let should_remove_kind =
|
let should_remove_kind =
|
||||||
quasis[0].raw.value.contains('\r') || quasis[0].raw.value.contains('`');
|
quasis[0].raw.value.contains('\r') || quasis[0].raw.value.contains('`');
|
||||||
|
|
||||||
let mut s = quasis[0]
|
let mut s = quasis[0].cooked.clone().unwrap();
|
||||||
.cooked
|
|
||||||
.clone()
|
|
||||||
.unwrap_or_else(|| quasis[0].raw.clone());
|
|
||||||
|
|
||||||
// See https://github.com/swc-project/swc/issues/1488
|
// See https://github.com/swc-project/swc/issues/1488
|
||||||
//
|
//
|
||||||
@ -319,9 +316,9 @@ impl VisitMut for TemplateLiteral {
|
|||||||
elems: quasis
|
elems: quasis
|
||||||
.take()
|
.take()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|elem| {
|
.map(|elem| match elem.cooked {
|
||||||
Lit::Str(elem.cooked.unwrap_or(elem.raw))
|
Some(cooked) => Lit::Str(cooked).as_arg(),
|
||||||
.as_arg()
|
None => undefined(DUMMY_SP).as_arg(),
|
||||||
})
|
})
|
||||||
.map(Some)
|
.map(Some)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -149,8 +149,6 @@ expect(fn).toThrow(TypeError);"#
|
|||||||
);
|
);
|
||||||
|
|
||||||
test!(
|
test!(
|
||||||
// TODO: Fix parser
|
|
||||||
ignore,
|
|
||||||
syntax(),
|
syntax(),
|
||||||
|_| tr(Default::default()),
|
|_| tr(Default::default()),
|
||||||
template_revision,
|
template_revision,
|
||||||
@ -165,99 +163,122 @@ function a() {
|
|||||||
var undefined = 4;
|
var undefined = 4;
|
||||||
tag`\01`;
|
tag`\01`;
|
||||||
}"#,
|
}"#,
|
||||||
r#"
|
r#"function _templateObject() {
|
||||||
function _templateObject8() {
|
const data = _taggedTemplateLiteral([
|
||||||
const data = _taggedTemplateLiteral([void 0], ["\\01"]);
|
void 0
|
||||||
|
], [
|
||||||
_templateObject8 = function () {
|
"\\unicode and \\u{55}"
|
||||||
|
]);
|
||||||
|
_templateObject = function() {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
return data;
|
return data;
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
function _templateObject1() {
|
||||||
function _templateObject7() {
|
const data = _taggedTemplateLiteral([
|
||||||
const data = _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u{-0}", "right"]);
|
void 0
|
||||||
|
], [
|
||||||
_templateObject7 = function () {
|
"\\01"
|
||||||
|
]);
|
||||||
|
_templateObject1 = function() {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
return data;
|
return data;
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _templateObject6() {
|
|
||||||
const data = _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u000g", "right"]);
|
|
||||||
|
|
||||||
_templateObject6 = function () {
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _templateObject5() {
|
|
||||||
const data = _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\xg", "right"]);
|
|
||||||
|
|
||||||
_templateObject5 = function () {
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _templateObject4() {
|
|
||||||
const data = _taggedTemplateLiteral(["left", void 0], ["left", "\\xg"]);
|
|
||||||
|
|
||||||
_templateObject4 = function () {
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _templateObject3() {
|
|
||||||
const data = _taggedTemplateLiteral([void 0, "right"], ["\\xg", "right"]);
|
|
||||||
|
|
||||||
_templateObject3 = function () {
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _templateObject2() {
|
function _templateObject2() {
|
||||||
const data = _taggedTemplateLiteral([void 0], ["\\01"]);
|
const data = _taggedTemplateLiteral([
|
||||||
|
void 0,
|
||||||
_templateObject2 = function () {
|
"right"
|
||||||
|
], [
|
||||||
|
"\\xg",
|
||||||
|
"right"
|
||||||
|
]);
|
||||||
|
_templateObject2 = function() {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
return data;
|
return data;
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
function _templateObject3() {
|
||||||
function _templateObject() {
|
const data = _taggedTemplateLiteral([
|
||||||
const data = _taggedTemplateLiteral([void 0], ["\\unicode and \\u{55}"]);
|
"left",
|
||||||
|
void 0
|
||||||
_templateObject = function () {
|
], [
|
||||||
|
"left",
|
||||||
|
"\\xg"
|
||||||
|
]);
|
||||||
|
_templateObject3 = function() {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
function _templateObject4() {
|
||||||
|
const data = _taggedTemplateLiteral([
|
||||||
|
"left",
|
||||||
|
void 0,
|
||||||
|
"right"
|
||||||
|
], [
|
||||||
|
"left",
|
||||||
|
"\\xg",
|
||||||
|
"right"
|
||||||
|
]);
|
||||||
|
_templateObject4 = function() {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
function _templateObject5() {
|
||||||
|
const data = _taggedTemplateLiteral([
|
||||||
|
"left",
|
||||||
|
void 0,
|
||||||
|
"right"
|
||||||
|
], [
|
||||||
|
"left",
|
||||||
|
"\\u000g",
|
||||||
|
"right"
|
||||||
|
]);
|
||||||
|
_templateObject5 = function() {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
function _templateObject6() {
|
||||||
|
const data = _taggedTemplateLiteral([
|
||||||
|
"left",
|
||||||
|
void 0,
|
||||||
|
"right"
|
||||||
|
], [
|
||||||
|
"left",
|
||||||
|
"\\u{-0}",
|
||||||
|
"right"
|
||||||
|
]);
|
||||||
|
_templateObject6 = function() {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
function _templateObject7() {
|
||||||
|
const data = _taggedTemplateLiteral([
|
||||||
|
void 0
|
||||||
|
], [
|
||||||
|
"\\01"
|
||||||
|
]);
|
||||||
|
_templateObject7 = function() {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
return data;
|
return data;
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tag(_templateObject());
|
tag(_templateObject());
|
||||||
tag(_templateObject2());
|
tag(_templateObject1());
|
||||||
|
tag(_templateObject2(), 0);
|
||||||
tag(_templateObject3(), 0);
|
tag(_templateObject3(), 0);
|
||||||
tag(_templateObject4(), 0);
|
tag(_templateObject4(), 0, 1);
|
||||||
tag(_templateObject5(), 0, 1);
|
tag(_templateObject5(), 0, 1);
|
||||||
tag(_templateObject6(), 0, 1);
|
tag(_templateObject6(), 0, 1);
|
||||||
tag(_templateObject7(), 0, 1);
|
|
||||||
|
|
||||||
function a() {
|
function a() {
|
||||||
var undefined = 4;
|
var undefined = 4;
|
||||||
tag(_templateObject8());
|
tag(_templateObject7());
|
||||||
}"#
|
}"#,
|
||||||
|
ok_if_code_eq
|
||||||
);
|
);
|
||||||
|
|
||||||
// default_order_exec
|
// default_order_exec
|
||||||
|
Loading…
Reference in New Issue
Block a user