mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 14:16:12 +03:00
Fix codegen: preserve input (#1221)
swc_ecma_codegen: - Preserve input. (#1204)
This commit is contained in:
parent
4294b5e7ba
commit
6888c69bda
@ -6,7 +6,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_ecmascript"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.14.1"
|
||||
version = "0.14.2"
|
||||
|
||||
[features]
|
||||
codegen = ["swc_ecma_codegen"]
|
||||
@ -21,7 +21,7 @@ react = ["swc_ecma_transforms", "swc_ecma_transforms/react"]
|
||||
|
||||
[dependencies]
|
||||
swc_ecma_ast = {version = "0.35.0", path = "./ast"}
|
||||
swc_ecma_codegen = {version = "0.41.0", path = "./codegen", optional = true}
|
||||
swc_ecma_codegen = {version = "0.41.1", path = "./codegen", optional = true}
|
||||
swc_ecma_dep_graph = {version = "0.9.0", path = "./dep-graph", optional = true}
|
||||
swc_ecma_parser = {version = "0.43.0", path = "./parser", optional = true}
|
||||
swc_ecma_transforms = {version = "0.30.1", path = "./transforms", optional = true}
|
||||
|
@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"]
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_ecma_codegen"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.41.0"
|
||||
version = "0.41.1"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1"
|
||||
|
@ -382,19 +382,17 @@ impl<'a> Emitter<'a> {
|
||||
fn emit_str_lit(&mut self, node: &Str) -> Result {
|
||||
self.emit_leading_comments_of_pos(node.span().lo())?;
|
||||
|
||||
let single_quote = if let Ok(s) = self.cm.span_to_snippet(node.span) {
|
||||
s.starts_with("'")
|
||||
} else {
|
||||
true
|
||||
};
|
||||
let single_quote = is_single_quote(&self.cm, node.span);
|
||||
|
||||
// if let Some(s) = get_text_of_node(&self.cm, node, false) {
|
||||
// self.wr.write_str_lit(node.span, &s)?;
|
||||
// return Ok(());
|
||||
// }
|
||||
let value = escape(&node.value);
|
||||
let value = escape(&self.cm, node.span, &node.value, single_quote);
|
||||
// let value = node.value.replace("\n", "\\n");
|
||||
|
||||
let single_quote = single_quote.unwrap_or(false);
|
||||
|
||||
if single_quote {
|
||||
punct!("'");
|
||||
self.wr.write_str_lit(node.span, &value)?;
|
||||
@ -2414,33 +2412,151 @@ fn unescape(s: &str) -> String {
|
||||
result
|
||||
}
|
||||
|
||||
fn escape(s: &str) -> Cow<str> {
|
||||
// let patterns = &[
|
||||
// "\\", "\u{0008}", "\u{000C}", "\n", "\r", "\t", "\u{000B}", "\00", "\01",
|
||||
// "\02", "\03", "\04", "\05", "\06", "\07", "\08", "\09", "\0",
|
||||
// ];
|
||||
// let replace_with = &[
|
||||
// "\\\\", "\\b", "\\f", "\\n", "\\r", "\\t", "\\v", "\\x000", "\\x001",
|
||||
// "\\x002", "\\x003", "\\x004", "\\x005", "\\x006", "\\x007", "\\x008",
|
||||
// "\\x009", "\\0", ];
|
||||
fn escape<'s>(cm: &SourceMap, span: Span, s: &'s str, single_quote: Option<bool>) -> Cow<'s, str> {
|
||||
if span.is_dummy() {
|
||||
return Cow::Owned(s.escape_default().to_string());
|
||||
}
|
||||
|
||||
//
|
||||
// {
|
||||
// let mut found = false;
|
||||
// for pat in patterns {
|
||||
// if s.contains(pat) {
|
||||
// found = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if !found {
|
||||
// return Cow::Borrowed(s);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// let ac = AhoCorasick::new(patterns);
|
||||
//
|
||||
// Cow::Owned(ac.replace_all(s, replace_with))
|
||||
Cow::Owned(s.escape_default().to_string())
|
||||
let orig = cm.span_to_snippet(span);
|
||||
let orig = match orig {
|
||||
Ok(orig) => orig,
|
||||
Err(v) => {
|
||||
return Cow::Owned(s.escape_default().to_string());
|
||||
}
|
||||
};
|
||||
|
||||
if orig.len() <= 2 {
|
||||
return Cow::Owned(s.escape_default().to_string());
|
||||
}
|
||||
|
||||
let mut orig = &*orig;
|
||||
|
||||
if (single_quote == Some(true) && orig.starts_with('\''))
|
||||
|| (single_quote == Some(false) && orig.starts_with('"'))
|
||||
{
|
||||
orig = &orig[1..orig.len() - 1];
|
||||
} else {
|
||||
return Cow::Owned(s.escape_default().to_string());
|
||||
}
|
||||
|
||||
let mut buf = String::with_capacity(s.len());
|
||||
let mut orig_iter = orig.chars().peekable();
|
||||
let mut s_iter = s.chars();
|
||||
|
||||
while let Some(orig_c) = orig_iter.next() {
|
||||
if orig_c == '\\' {
|
||||
buf.push('\\');
|
||||
match orig_iter.next() {
|
||||
Some('\\') => {
|
||||
buf.push('\\');
|
||||
s_iter.next();
|
||||
continue;
|
||||
}
|
||||
Some(escaper) => {
|
||||
buf.push(escaper);
|
||||
match escaper {
|
||||
'x' => {
|
||||
buf.extend(orig_iter.next());
|
||||
buf.extend(orig_iter.next());
|
||||
s_iter.next();
|
||||
}
|
||||
'u' => match orig_iter.next() {
|
||||
Some('{') => {
|
||||
loop {
|
||||
if orig_iter.next() == Some('}') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_iter.next();
|
||||
}
|
||||
Some(ch) => {
|
||||
buf.push(ch);
|
||||
buf.extend(orig_iter.next());
|
||||
buf.extend(orig_iter.next());
|
||||
buf.extend(orig_iter.next());
|
||||
s_iter.next();
|
||||
}
|
||||
None => break,
|
||||
},
|
||||
'b' | 'f' | 'n' | 'r' | 't' | 'v' | '0' => {
|
||||
s_iter.next();
|
||||
}
|
||||
|
||||
'\'' if single_quote == Some(true) => {
|
||||
s_iter.next();
|
||||
}
|
||||
|
||||
'"' if single_quote == Some(false) => {
|
||||
s_iter.next();
|
||||
}
|
||||
|
||||
_ => {
|
||||
buf.extend(s_iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
s_iter.next();
|
||||
buf.push(orig_c);
|
||||
}
|
||||
|
||||
buf.extend(s_iter);
|
||||
|
||||
Cow::Owned(buf)
|
||||
}
|
||||
|
||||
/// Returns [Some] if the span points to a string literal written by user.
|
||||
///
|
||||
/// Returns [None] if the span is created from a pass of swc. For example,
|
||||
/// spans of string literals created from [TplElement] do not have `starting`
|
||||
/// quote.
|
||||
fn is_single_quote(cm: &SourceMap, span: Span) -> Option<bool> {
|
||||
// This is a workaround for TplElement issue.
|
||||
if span.ctxt != SyntaxContext::empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let start = cm.lookup_byte_offset(span.lo);
|
||||
let end = cm.lookup_byte_offset(span.hi);
|
||||
|
||||
if start.sf.start_pos != end.sf.start_pos {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Empty file
|
||||
if start.sf.start_pos == start.sf.end_pos {
|
||||
return None;
|
||||
}
|
||||
|
||||
let start_index = start.pos.0;
|
||||
let end_index = end.pos.0;
|
||||
let source_len = (start.sf.end_pos - start.sf.start_pos).0;
|
||||
|
||||
if start_index > end_index || end_index > source_len {
|
||||
return None;
|
||||
}
|
||||
|
||||
let src = &start.sf.src;
|
||||
let single_quote = match src.as_bytes()[start_index as usize] {
|
||||
b'\'' => true,
|
||||
b'"' => false,
|
||||
_ => return None,
|
||||
};
|
||||
if end_index == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
if src.as_bytes()[start_index as usize] != src.as_bytes()[(end_index - 1) as usize] {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(single_quote)
|
||||
}
|
||||
|
||||
#[cold]
|
||||
|
@ -167,10 +167,10 @@ fn no_octal_escape() {
|
||||
'\x000';
|
||||
'\x001';
|
||||
'\x009'"#,
|
||||
r#"'\u{0}a';
|
||||
'\u{0}0';
|
||||
'\u{0}1';
|
||||
'\u{0}9';"#,
|
||||
r#"'\x00a';
|
||||
'\x000';
|
||||
'\x001';
|
||||
'\x009';"#,
|
||||
);
|
||||
}
|
||||
|
||||
@ -432,6 +432,44 @@ fn jsx_1() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deno_8162() {
|
||||
test_from_to(
|
||||
r#""\x00\r\n\x85\u2028\u2029";"#,
|
||||
r#""\x00\r\n\x85\u2028\u2029";"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integration_01() {
|
||||
test_from_to(
|
||||
r#"
|
||||
`Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` +
|
||||
`"${unexpectedKeys.join('", "')}" found in ${argumentName}. ` +
|
||||
`Expected to find one of the known reducer keys instead: ` +
|
||||
`"${reducerKeys.join('", "')}". Unexpected keys will be ignored.`
|
||||
"#,
|
||||
"
|
||||
`Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` + `\"${unexpectedKeys.join('\", \
|
||||
\"')}\" found in ${argumentName}. ` + `Expected to find one of the known reducer keys \
|
||||
instead: ` + `\"${reducerKeys.join('\", \"')}\". Unexpected keys will be ignored.`;
|
||||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integration_01_reduced_01() {
|
||||
test_from_to(
|
||||
r#"
|
||||
`Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` +
|
||||
`"${unexpectedKeys.join('", "')}" found in ${argumentName}. `
|
||||
"#,
|
||||
"
|
||||
`Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` + `\"${unexpectedKeys.join('\", \
|
||||
\"')}\" found in ${argumentName}. `;",
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Buf(Arc<RwLock<Vec<u8>>>);
|
||||
impl Write for Buf {
|
||||
|
@ -1,2 +1,2 @@
|
||||
'use strict';
|
||||
'use\x20strict';
|
||||
with (a)b = c;
|
||||
|
@ -1 +1 @@
|
||||
"a";
|
||||
"\u0061";
|
||||
|
@ -1 +1 @@
|
||||
'\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\t\n\u{b}\u{c}\r\u{e}\u{f}\u{10}\u{11}\u{12}\u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f} !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u{7f}\u{80}\u{81}\u{82}\u{83}\u{84}\u{85}\u{86}\u{87}\u{88}\u{89}\u{8a}\u{8b}\u{8c}\u{8d}\u{8e}\u{8f}\u{90}\u{91}\u{92}\u{93}\u{94}\u{95}\u{96}\u{97}\u{98}\u{99}\u{9a}\u{9b}\u{9c}\u{9d}\u{9e}\u{9f}\u{a0}\u{a1}\u{a2}\u{a3}\u{a4}\u{a5}\u{a6}\u{a7}\u{a8}\u{a9}\u{aa}\u{ab}\u{ac}\u{ad}\u{ae}\u{af}\u{b0}\u{b1}\u{b2}\u{b3}\u{b4}\u{b5}\u{b6}\u{b7}\u{b8}\u{b9}\u{ba}\u{bb}\u{bc}\u{bd}\u{be}\u{bf}\u{c0}\u{c1}\u{c2}\u{c3}\u{c4}\u{c5}\u{c6}\u{c7}\u{c8}\u{c9}\u{ca}\u{cb}\u{cc}\u{cd}\u{ce}\u{cf}\u{d0}\u{d1}\u{d2}\u{d3}\u{d4}\u{d5}\u{d6}\u{d7}\u{d8}\u{d9}\u{da}\u{db}\u{dc}\u{dd}\u{de}\u{df}\u{e0}\u{e1}\u{e2}\u{e3}\u{e4}\u{e5}\u{e6}\u{e7}\u{e8}\u{e9}\u{ea}\u{eb}\u{ec}\u{ed}\u{ee}\u{ef}\u{f0}\u{f1}\u{f2}\u{f3}\u{f4}\u{f5}\u{f6}\u{f7}\u{f8}\u{f9}\u{fa}\u{fb}\u{fc}\u{fd}\u{fe}' + a;
|
||||
'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe' + a;
|
||||
|
@ -1 +1 @@
|
||||
"Hello\nWorld";
|
||||
"Hello\012World";
|
||||
|
@ -1 +1,2 @@
|
||||
"Helloworld";
|
||||
"Hello\
w
|
||||
world";
|
||||
|
@ -1 +1 @@
|
||||
"Hello\u{ca}World";
|
||||
"Hello\3Ê12World";
|
||||
|
@ -1 +1 @@
|
||||
('\u{10ffff}');
|
||||
('\u');
|
||||
|
@ -1 +1 @@
|
||||
"Hello92World";
|
||||
"Hello\7912World";
|
||||
|
@ -1 +1 @@
|
||||
('I1');
|
||||
('\1I111');
|
||||
|
@ -1 +1 @@
|
||||
"4";
|
||||
"\u";
|
||||
|
@ -1 +1 @@
|
||||
('\u{1}');
|
||||
('\1');
|
||||
|
@ -1,2 +1,2 @@
|
||||
'use strict';
|
||||
('\u{0}');
|
||||
('\0');
|
||||
|
@ -1 +1,2 @@
|
||||
"Helloworld";
|
||||
"Hello\
|
||||
wworld";
|
||||
|
@ -1,2 +1,2 @@
|
||||
'use strict';
|
||||
('\u{0}x');
|
||||
('\0x');
|
||||
|
@ -1 +1 @@
|
||||
('\u{5}a');
|
||||
('\5a');
|
||||
|
@ -1 +1 @@
|
||||
"Hello!2World";
|
||||
"Hello\4!12World";
|
||||
|
@ -1 +1 @@
|
||||
"\n\r\t\u{b}\u{8}\u{c}\\\'\"\u{0}";
|
||||
"\n\r\t\v\b\f\\\''\"\0";
|
||||
|
@ -1 +1 @@
|
||||
('\u{f8}');
|
||||
('\u');
|
||||
|
@ -1 +1 @@
|
||||
"Hello\u{0}World";
|
||||
"Hello\0World";
|
||||
|
@ -1 +1 @@
|
||||
('\u{202a}');
|
||||
('');
|
||||
|
@ -1 +1 @@
|
||||
('a');
|
||||
('\aa');
|
||||
|
@ -1,5 +1,5 @@
|
||||
a["b"] = "c";
|
||||
a["if"] = "if";
|
||||
a["*"] = "d";
|
||||
a["\u{eb3}"] = "e";
|
||||
a["\u0EB3"] = "e";
|
||||
a[""] = "f";
|
||||
|
@ -1 +1 @@
|
||||
('\t');
|
||||
('\1 1');
|
||||
|
@ -1 +1,2 @@
|
||||
('');
|
||||
('\
|
||||
');
|
||||
|
@ -1 +1 @@
|
||||
"\u{714e}\u{8336}";
|
||||
"\u\u";
|
||||
|
@ -1 +1 @@
|
||||
"Hello\u{2}World";
|
||||
"Hello\02World";
|
||||
|
@ -1,4 +1,4 @@
|
||||
function a() {
|
||||
'use strict';
|
||||
"\u{0}";
|
||||
"\0";
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
'a&b';
|
||||
'a\u0026b';
|
||||
|
@ -1 +1 @@
|
||||
('\u{0}');
|
||||
('\0');
|
||||
|
@ -1,4 +1,4 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
'use\x20strict';
|
||||
with (a);
|
||||
}());
|
||||
|
@ -1 +1 @@
|
||||
('\u{7}a');
|
||||
('\7a');
|
||||
|
@ -1 +1 @@
|
||||
('I');
|
||||
('\1I11');
|
||||
|
@ -1 +1 @@
|
||||
('`');
|
||||
('\``');
|
||||
|
@ -1 +1,2 @@
|
||||
('');
|
||||
('\
|
||||
');
|
||||
|
@ -1,2 +1,2 @@
|
||||
"use strict";
|
||||
"use\x20strict";
|
||||
with (a)b = c;
|
||||
|
@ -1 +1 @@
|
||||
"HelloRWorld";
|
||||
"Hello\1R22World";
|
||||
|
@ -1 +1 @@
|
||||
('');
|
||||
('\
');
|
||||
|
@ -1 +1 @@
|
||||
('\u{1}');
|
||||
('\01');
|
||||
|
Binary file not shown.
@ -1 +1 @@
|
||||
('\u{89}1');
|
||||
('\2111');
|
||||
|
@ -1,4 +1,4 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
'use\x20strict';
|
||||
with (a);
|
||||
});
|
||||
|
@ -1 +1 @@
|
||||
('\u{f8}');
|
||||
('\u');
|
||||
|
@ -1 +1 @@
|
||||
(')11');
|
||||
('\5)111');
|
||||
|
@ -1 +1 @@
|
||||
"Hello\n2World";
|
||||
"Hello\0122World";
|
||||
|
@ -1 +1 @@
|
||||
('\u{0}');
|
||||
('\u');
|
||||
|
@ -1 +1 @@
|
||||
('');
|
||||
('\
');
|
||||
|
@ -1 +1 @@
|
||||
('');
|
||||
('\
');
|
||||
|
@ -1 +1 @@
|
||||
a("\u{b}");
|
||||
a("\v");
|
||||
|
@ -1 +1 @@
|
||||
"\u{20bb7}\u{91ce}\u{5bb6}";
|
||||
"\u\u\u";
|
||||
|
@ -1,6 +1,6 @@
|
||||
a["b"] = "c";
|
||||
a["if"] = "if";
|
||||
a["*"] = "d";
|
||||
a["\u{eb3}"] = "e";
|
||||
a["\u0EB3"] = "e";
|
||||
a[""] = "f";
|
||||
a["1_1"] = "b";
|
||||
|
@ -1 +1 @@
|
||||
"Hello\u{1}World";
|
||||
"Hello\1World";
|
||||
|
@ -1 +1 @@
|
||||
"a";
|
||||
"\x61";
|
||||
|
@ -1,17 +1,23 @@
|
||||
use crate::util::{is_literal, prepend_stmts, ExprFactory, StmtLike};
|
||||
use std::{iter, mem};
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{BytePos, Spanned, DUMMY_SP};
|
||||
use swc_common::{BytePos, Mark, Spanned, SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn template_literal() -> impl Fold {
|
||||
TemplateLiteral::default()
|
||||
TemplateLiteral {
|
||||
added: Default::default(),
|
||||
str_ctxt: SyntaxContext::empty().apply_mark(Mark::fresh(Mark::root())),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TemplateLiteral {
|
||||
added: Vec<Stmt>,
|
||||
/// Applied to [Str] created by this pass.
|
||||
///
|
||||
/// This is to workaround codegen issue.
|
||||
str_ctxt: SyntaxContext,
|
||||
}
|
||||
|
||||
impl Fold for TemplateLiteral {
|
||||
@ -63,7 +69,9 @@ impl Fold for TemplateLiteral {
|
||||
|
||||
match quasis.next() {
|
||||
Some(TplElement { cooked, raw, .. }) => {
|
||||
Box::new(Lit::Str(cooked.unwrap_or_else(|| raw)).into())
|
||||
let mut s = cooked.unwrap_or_else(|| raw);
|
||||
s.span.ctxt = self.str_ctxt;
|
||||
Box::new(Lit::Str(s).into())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -806,3 +806,104 @@ test!(
|
||||
}
|
||||
"
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_01,
|
||||
"`\"`",
|
||||
r#""\"""#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_02,
|
||||
"`\"\"`",
|
||||
r#"
|
||||
"\"\""
|
||||
"#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_03,
|
||||
"`\"${foo}`",
|
||||
r#"
|
||||
"\"".concat(foo);
|
||||
"#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_04,
|
||||
"`\"${foo}\"`",
|
||||
r#"
|
||||
"\"".concat(foo, "\"");
|
||||
"#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_05,
|
||||
"`\"\"${foo}\"\"`",
|
||||
r#"
|
||||
"\"\"".concat(foo, "\"\"");
|
||||
"#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_06,
|
||||
"\"``\"",
|
||||
"\"``\"",
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_07,
|
||||
r#"`The ${argumentName} has unexpected type of "`"#,
|
||||
r#""The ".concat(argumentName, " has unexpected type of \"");"#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_08,
|
||||
r#"`". Expected argument to be an object with the following `"#,
|
||||
r#""\". Expected argument to be an object with the following ";"#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_09,
|
||||
r#"`keys: "${reducerKeys.join('", "')}"`"#,
|
||||
r#""keys: \"".concat(reducerKeys.join('\", \"'), "\"");"#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|_| tr(Default::default()),
|
||||
codegen_10,
|
||||
r#"`The ${argumentName} has unexpected type of "` +
|
||||
matchType +
|
||||
`". Expected argument to be an object with the following ` +
|
||||
`keys: "${reducerKeys.join('", "')}"`"#,
|
||||
r#""The ".concat(argumentName, " has unexpected type of \"") + matchType + "\". Expected argument to be an object with the following " + "keys: \"".concat(reducerKeys.join('", "'), "\"")"#,
|
||||
ok_if_code_eq
|
||||
);
|
||||
|
@ -1037,7 +1037,7 @@ class ServerRequest {
|
||||
if (transferEncoding != null) {
|
||||
const parts = transferEncoding.split(",").map((e)=>e.trim().toLowerCase()
|
||||
);
|
||||
assert3(parts.includes("chunked"), 'transfer-encoding must include \"chunked\" if content-length is not set');
|
||||
assert3(parts.includes("chunked"), 'transfer-encoding must include "chunked" if content-length is not set');
|
||||
this._body = chunkedBodyReader2(this.headers, this.r);
|
||||
} else // Neither content-length nor transfer-encoding: chunked
|
||||
this._body = emptyReader2();
|
||||
|
@ -363,7 +363,7 @@ class ServerRequest {
|
||||
if (transferEncoding != null) {
|
||||
const parts = transferEncoding.split(",").map((e)=>e.trim().toLowerCase()
|
||||
);
|
||||
assert(parts.includes("chunked"), 'transfer-encoding must include \"chunked\" if content-length is not set');
|
||||
assert(parts.includes("chunked"), 'transfer-encoding must include "chunked" if content-length is not set');
|
||||
this._body = chunkedBodyReader2(this.headers, this.r);
|
||||
} else // Neither content-length nor transfer-encoding: chunked
|
||||
this._body = emptyReader2();
|
||||
|
@ -565,3 +565,11 @@ fn issue_1203() {
|
||||
|
||||
assert!(!f.contains("return //"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codegen_1() {
|
||||
let f = file("tests/projects/codegen-1/input.js").unwrap();
|
||||
println!("{}", f);
|
||||
|
||||
assert_eq!(f.to_string(), "\"\\\"\";\n");
|
||||
}
|
||||
|
1
tests/projects/codegen-1/input.js
Normal file
1
tests/projects/codegen-1/input.js
Normal file
@ -0,0 +1 @@
|
||||
`"`
|
Loading…
Reference in New Issue
Block a user