mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-14 23:10:02 -04:00
rewrite... TWO!!
This commit is contained in:
parent
6d03da6d85
commit
6edad29dbb
9 changed files with 273 additions and 135 deletions
|
@ -65,8 +65,6 @@ fn main() -> Result<()> {
|
||||||
eprintln!("{}", err.with_source_code(source.clone()));
|
eprintln!("{}", err.with_source_code(source.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("changes: {:#?}", res.changes);
|
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"rewritten:\n{}",
|
"rewritten:\n{}",
|
||||||
String::from_utf8(res.js).context("failed to parse rewritten js")?
|
String::from_utf8(res.js).context("failed to parse rewritten js")?
|
||||||
|
@ -160,6 +158,10 @@ function $wrap(val) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const $gwrap = $wrap;
|
||||||
|
|
||||||
|
function $scramitize(val) { return val }
|
||||||
|
|
||||||
function assert(val) {
|
function assert(val) {
|
||||||
if (!val) fail();
|
if (!val) fail();
|
||||||
}
|
}
|
||||||
|
@ -172,7 +174,7 @@ function check(val) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let rewritten = dorewrite(&content).unwrap();
|
let rewritten = dorewrite(&content).unwrap();
|
||||||
println!("{:?}", rewritten);
|
println!("{}", std::str::from_utf8(&rewritten.js).unwrap());
|
||||||
|
|
||||||
context.eval(Source::from_bytes(&rewritten.js)).unwrap();
|
context.eval(Source::from_bytes(&rewritten.js)).unwrap();
|
||||||
println!("PASS");
|
println!("PASS");
|
||||||
|
|
5
rewriter/native/tests/0-sanity.js
Normal file
5
rewriter/native/tests/0-sanity.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
check(window);
|
||||||
|
check(this);
|
||||||
|
check(globalThis);
|
||||||
|
check(location);
|
||||||
|
check(globalThis["win" + "dow"])
|
3
rewriter/native/tests/1-destructure.js
Normal file
3
rewriter/native/tests/1-destructure.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const { location: x } = globalThis;
|
||||||
|
|
||||||
|
check(x);
|
6
rewriter/native/tests/2-function-default.js
Normal file
6
rewriter/native/tests/2-function-default.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
function f(g = globalThis, l = location) {
|
||||||
|
check(g);
|
||||||
|
check(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
f();
|
7
rewriter/native/tests/3-shadow-globals.js
Normal file
7
rewriter/native/tests/3-shadow-globals.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
function f(location, globalThis) {
|
||||||
|
assert(location === 1)
|
||||||
|
assert(globalThis === 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
f(1, 2);
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
let reached = false
|
||||||
|
let eval = (t) => t === "location = 1" && (reached = true)
|
||||||
|
|
||||||
|
// testing to make sure this doesn't get rewritten
|
||||||
|
eval("location = 1")
|
||||||
|
|
||||||
|
if (!reached) fail();
|
3
rewriter/native/tests/for-assignment.js.disabled
Normal file
3
rewriter/native/tests/for-assignment.js.disabled
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
for (location of ["https://google.com"]) {
|
||||||
|
//
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ use smallvec::{smallvec, SmallVec};
|
||||||
use crate::{cfg::Config, RewriterError};
|
use crate::{cfg::Config, RewriterError};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum Rewrite {
|
pub(crate) enum Rewrite {
|
||||||
/// `(cfg.wrapfn(ident))` | `cfg.wrapfn(ident)`
|
/// `(cfg.wrapfn(ident))` | `cfg.wrapfn(ident)`
|
||||||
WrapFn {
|
WrapFn {
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -52,7 +52,7 @@ pub enum Rewrite {
|
||||||
rhsspan: Span,
|
rhsspan: Span,
|
||||||
op: AssignmentOperator,
|
op: AssignmentOperator,
|
||||||
},
|
},
|
||||||
/// `ident,` -> `ident: cfg.wrapfn(ident)`
|
/// `ident,` -> `ident: cfg.wrapfn(ident),`
|
||||||
ShorthandObj {
|
ShorthandObj {
|
||||||
span: Span,
|
span: Span,
|
||||||
name: CompactStr,
|
name: CompactStr,
|
||||||
|
@ -73,93 +73,228 @@ pub enum Rewrite {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rewrite {
|
impl Rewrite {
|
||||||
pub fn get_span(&self) -> &Span {
|
fn into_inner(self) -> SmallVec<[JsChange; 4]> {
|
||||||
match self {
|
match self {
|
||||||
Self::WrapFn { span, .. } => span,
|
Self::WrapFn { wrapped, span } => {
|
||||||
Self::SetRealmFn { span, .. } => span,
|
let start = Span::new(span.start, span.start);
|
||||||
Self::WrapThisFn { span } => span,
|
let end = Span::new(span.end, span.end);
|
||||||
Self::ImportFn { span } => span,
|
if wrapped {
|
||||||
Self::MetaFn { span } => span,
|
smallvec![
|
||||||
|
JsChange::WrapFn {
|
||||||
|
span: start,
|
||||||
|
extra: true
|
||||||
|
},
|
||||||
|
JsChange::DoubleClosingParen { span: end }
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
smallvec![
|
||||||
|
JsChange::WrapFn {
|
||||||
|
span: start,
|
||||||
|
extra: false
|
||||||
|
},
|
||||||
|
JsChange::ClosingParen {
|
||||||
|
span: end,
|
||||||
|
semi: false,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::SetRealmFn { span } => smallvec![JsChange::SetRealmFn { span }],
|
||||||
|
Self::WrapThisFn { span } => smallvec![
|
||||||
|
JsChange::WrapThisFn {
|
||||||
|
span: Span::new(span.start, span.start)
|
||||||
|
},
|
||||||
|
JsChange::ClosingParen {
|
||||||
|
span: Span::new(span.end, span.end),
|
||||||
|
semi: false,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
Self::ImportFn { span } => smallvec![JsChange::ImportFn { span }],
|
||||||
|
Self::MetaFn { span } => smallvec![JsChange::MetaFn { span }],
|
||||||
|
|
||||||
Self::ScramErr { span, .. } => span,
|
Self::ScramErr { span, .. } => {
|
||||||
Self::Scramitize { span } => span,
|
smallvec![
|
||||||
|
JsChange::ScramErrFn {
|
||||||
|
span: Span::new(span.start, span.start)
|
||||||
|
},
|
||||||
|
JsChange::ClosingParen {
|
||||||
|
span: Span::new(span.end, span.end),
|
||||||
|
semi: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Self::Scramitize { span } => {
|
||||||
|
smallvec![
|
||||||
|
JsChange::ScramitizeFn {
|
||||||
|
span: Span::new(span.start, span.start)
|
||||||
|
},
|
||||||
|
JsChange::ClosingParen {
|
||||||
|
span: Span::new(span.end, span.end),
|
||||||
|
semi: false,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
Self::Eval { span, .. } => span,
|
Self::Eval { inner, span } => smallvec![
|
||||||
Self::Assignment { entirespan, .. } => entirespan,
|
JsChange::EvalRewriteFn {
|
||||||
Self::ShorthandObj { span, .. } => span,
|
span: Span::new(span.start, inner.start)
|
||||||
Self::SourceTag { span, .. } => span,
|
},
|
||||||
|
JsChange::ReplaceClosingParen {
|
||||||
Self::Replace { span, .. } => span,
|
span: Span::new(inner.end, span.end),
|
||||||
Self::Delete { span } => span,
|
}
|
||||||
|
],
|
||||||
|
Self::Assignment {
|
||||||
|
name,
|
||||||
|
rhsspan,
|
||||||
|
op,
|
||||||
|
entirespan,
|
||||||
|
} => smallvec![
|
||||||
|
JsChange::AssignmentLeft {
|
||||||
|
name,
|
||||||
|
op,
|
||||||
|
span: Span::new(entirespan.start, rhsspan.start)
|
||||||
|
},
|
||||||
|
JsChange::ReplaceClosingParen {
|
||||||
|
span: Span::new(rhsspan.end, entirespan.end)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// maps to insert
|
||||||
|
Self::ShorthandObj { name, span } => smallvec![JsChange::ShorthandObj {
|
||||||
|
ident: name,
|
||||||
|
span: Span::new(span.end, span.end)
|
||||||
|
}],
|
||||||
|
// maps to insert
|
||||||
|
Self::SourceTag { tagname, span } => smallvec![JsChange::SourceTag { span, tagname }],
|
||||||
|
Self::Replace { text, span } => smallvec![JsChange::Replace { span, text }],
|
||||||
|
Self::Delete { span } => smallvec![JsChange::Delete { span }],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
enum JsChange {
|
||||||
|
/// insert `${cfg.wrapfn}(`
|
||||||
|
WrapFn { span: Span, extra: bool },
|
||||||
|
/// insert `${cfg.setrealmfn}({}).`
|
||||||
|
SetRealmFn { span: Span },
|
||||||
|
/// insert `${cfg.wrapthis}(`
|
||||||
|
WrapThisFn { span: Span },
|
||||||
|
/// insert `$scramerr(`
|
||||||
|
ScramErrFn { span: Span },
|
||||||
|
/// insert `$scramitize(`
|
||||||
|
ScramitizeFn { span: Span },
|
||||||
|
/// insert `eval(${cfg.rewritefn}(`
|
||||||
|
EvalRewriteFn { span: Span },
|
||||||
|
/// insert `: ${cfg.wrapfn}(ident)`
|
||||||
|
ShorthandObj { span: Span, ident: CompactStr },
|
||||||
|
/// insert scramtag
|
||||||
|
SourceTag { span: Span, tagname: String },
|
||||||
|
|
||||||
|
/// replace span with `(${cfg.importfn}("${cfg.base}")`
|
||||||
|
ImportFn { span: Span },
|
||||||
|
/// replace span with `${cfg.metafn}("${cfg.base}")`
|
||||||
|
MetaFn { span: Span },
|
||||||
|
/// replace span with `((t)=>$scramjet$tryset(${name},"${op}",t)||(${name}${op}t))(`
|
||||||
|
AssignmentLeft {
|
||||||
|
span: Span,
|
||||||
|
name: CompactStr,
|
||||||
|
op: AssignmentOperator,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// replace span with `)`
|
||||||
|
ReplaceClosingParen { span: Span },
|
||||||
|
/// insert `)`
|
||||||
|
ClosingParen { span: Span, semi: bool },
|
||||||
|
/// insert `))`
|
||||||
|
DoubleClosingParen { span: Span },
|
||||||
|
|
||||||
|
/// replace span with text
|
||||||
|
Replace { span: Span, text: String },
|
||||||
|
/// replace span with ""
|
||||||
|
Delete { span: Span },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JsChange {
|
||||||
|
fn get_span(&self) -> &Span {
|
||||||
|
match self {
|
||||||
|
Self::WrapFn { span, .. }
|
||||||
|
| Self::SetRealmFn { span }
|
||||||
|
| Self::WrapThisFn { span }
|
||||||
|
| Self::ScramErrFn { span }
|
||||||
|
| Self::ScramitizeFn { span }
|
||||||
|
| Self::EvalRewriteFn { span }
|
||||||
|
| Self::ShorthandObj { span, .. }
|
||||||
|
| Self::SourceTag { span, .. }
|
||||||
|
| Self::ImportFn { span }
|
||||||
|
| Self::MetaFn { span }
|
||||||
|
| Self::AssignmentLeft { span, .. }
|
||||||
|
| Self::ReplaceClosingParen { span }
|
||||||
|
| Self::ClosingParen { span, .. }
|
||||||
|
| Self::DoubleClosingParen { span }
|
||||||
|
| Self::Replace { span, .. }
|
||||||
|
| Self::Delete { span } => span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns (bunch of stuff to add before, option<bunch of stuff to add after>)
|
|
||||||
// bunch of stuff to add after should only be some if it's not a replace op
|
|
||||||
fn to_inner<'a, E>(&'a self, cfg: &'a Config<E>) -> JsChangeInner<'a>
|
fn to_inner<'a, E>(&'a self, cfg: &'a Config<E>) -> JsChangeInner<'a>
|
||||||
where
|
where
|
||||||
E: Fn(String) -> String,
|
E: Fn(String) -> String,
|
||||||
E: Clone,
|
E: Clone,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Self::WrapFn { wrapped, span } => {
|
Self::WrapFn { span, extra } => {
|
||||||
if *wrapped {
|
if *extra {
|
||||||
JsChangeInner::Wrap {
|
JsChangeInner::Insert {
|
||||||
before: smallvec!["(", cfg.wrapfn.as_str(), "("],
|
loc: span.start,
|
||||||
inner: span,
|
str: smallvec!["(", cfg.wrapfn.as_str(), "("],
|
||||||
after: smallvec!["))"],
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
JsChangeInner::Wrap {
|
JsChangeInner::Insert {
|
||||||
before: smallvec![cfg.wrapfn.as_str(), "("],
|
loc: span.start,
|
||||||
inner: span,
|
str: smallvec![cfg.wrapfn.as_str(), "("],
|
||||||
after: smallvec![")"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::SetRealmFn { span } => JsChangeInner::Wrap {
|
Self::SetRealmFn { span } => JsChangeInner::Insert {
|
||||||
before: smallvec![cfg.setrealmfn.as_str(), "({})."],
|
loc: span.start,
|
||||||
inner: span,
|
str: smallvec![cfg.setrealmfn.as_str(), "({})."],
|
||||||
after: smallvec![],
|
|
||||||
},
|
},
|
||||||
Self::WrapThisFn { span } => JsChangeInner::Wrap {
|
Self::WrapThisFn { span } => JsChangeInner::Insert {
|
||||||
before: smallvec![cfg.wrapthisfn.as_str(), "("],
|
loc: span.start,
|
||||||
inner: span,
|
str: smallvec![cfg.wrapthisfn.as_str(), "("],
|
||||||
after: smallvec![")"],
|
|
||||||
},
|
},
|
||||||
Self::ImportFn { .. } => JsChangeInner::Replace(smallvec![
|
Self::ScramErrFn { span } => JsChangeInner::Insert {
|
||||||
"(",
|
loc: span.start,
|
||||||
cfg.importfn.as_str(),
|
str: smallvec!["$scramerr("],
|
||||||
"(\"",
|
|
||||||
cfg.base.as_str(),
|
|
||||||
"\"))"
|
|
||||||
]),
|
|
||||||
Self::MetaFn { .. } => JsChangeInner::Replace(smallvec![
|
|
||||||
cfg.metafn.as_str(),
|
|
||||||
"(\"",
|
|
||||||
cfg.base.as_str(),
|
|
||||||
"\")"
|
|
||||||
]),
|
|
||||||
|
|
||||||
// maps to insert
|
|
||||||
Self::ScramErr { name, .. } => {
|
|
||||||
JsChangeInner::Replace(smallvec!["$scramerr(", name.as_str(), ");"])
|
|
||||||
}
|
|
||||||
Self::Scramitize { span } => JsChangeInner::Wrap {
|
|
||||||
before: smallvec!["$scramitize("],
|
|
||||||
inner: span,
|
|
||||||
after: smallvec![")"],
|
|
||||||
},
|
},
|
||||||
|
Self::ScramitizeFn { span } => JsChangeInner::Insert {
|
||||||
Self::Eval { inner, .. } => JsChangeInner::Wrap {
|
loc: span.start,
|
||||||
before: smallvec!["eval(", cfg.rewritefn.as_str(), "("],
|
str: smallvec!["$scramitize("],
|
||||||
inner,
|
|
||||||
after: smallvec![")"],
|
|
||||||
},
|
},
|
||||||
Self::Assignment {
|
Self::EvalRewriteFn { .. } => JsChangeInner::Replace {
|
||||||
name, rhsspan, op, ..
|
str: smallvec!["eval(", cfg.rewritefn.as_str(), "("],
|
||||||
} => JsChangeInner::Wrap {
|
},
|
||||||
before: smallvec![
|
Self::ShorthandObj { span, ident } => JsChangeInner::Insert {
|
||||||
|
loc: span.start,
|
||||||
|
str: smallvec![":", cfg.wrapfn.as_str(), "(", ident.as_str(), ")"],
|
||||||
|
},
|
||||||
|
Self::SourceTag { span, tagname } => JsChangeInner::Insert {
|
||||||
|
loc: span.start,
|
||||||
|
str: smallvec![
|
||||||
|
"/*scramtag ",
|
||||||
|
cfg.sourcetag.as_str(),
|
||||||
|
tagname.as_str(),
|
||||||
|
"*/"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Self::ImportFn { span } => JsChangeInner::Replace {
|
||||||
|
str: smallvec!["(", cfg.importfn.as_str(), "(\"", cfg.base.as_str(), "\")"],
|
||||||
|
},
|
||||||
|
Self::MetaFn { span } => JsChangeInner::Replace {
|
||||||
|
str: smallvec![cfg.metafn.as_str(), "(\"", cfg.base.as_str()],
|
||||||
|
},
|
||||||
|
Self::AssignmentLeft { span, name, op } => JsChangeInner::Replace {
|
||||||
|
str: smallvec![
|
||||||
"((t)=>$scramjet$tryset(",
|
"((t)=>$scramjet$tryset(",
|
||||||
name.as_str(),
|
name.as_str(),
|
||||||
",\"",
|
",\"",
|
||||||
|
@ -167,41 +302,39 @@ impl Rewrite {
|
||||||
"\",t)||(",
|
"\",t)||(",
|
||||||
name.as_str(),
|
name.as_str(),
|
||||||
op.as_str(),
|
op.as_str(),
|
||||||
"t))("
|
"t)("
|
||||||
],
|
],
|
||||||
inner: rhsspan,
|
|
||||||
after: smallvec![")"],
|
|
||||||
},
|
},
|
||||||
// maps to insert
|
Self::ReplaceClosingParen { span } => JsChangeInner::Replace {
|
||||||
Self::ShorthandObj { name, .. } => JsChangeInner::Replace(smallvec![
|
str: smallvec![")"],
|
||||||
name.as_str(),
|
},
|
||||||
":",
|
Self::ClosingParen { span, semi } => JsChangeInner::Insert {
|
||||||
cfg.wrapfn.as_str(),
|
loc: span.start,
|
||||||
"(",
|
str: if *semi {
|
||||||
name.as_str(),
|
smallvec![");"]
|
||||||
")"
|
} else {
|
||||||
]),
|
smallvec![")"]
|
||||||
// maps to insert
|
},
|
||||||
Self::SourceTag { tagname, .. } => JsChangeInner::Replace(smallvec![
|
},
|
||||||
"/*scramtag ",
|
Self::DoubleClosingParen { span } => JsChangeInner::Insert {
|
||||||
tagname.as_str(),
|
loc: span.start,
|
||||||
" ",
|
str: smallvec!["))"],
|
||||||
cfg.sourcetag.as_str(),
|
},
|
||||||
"*/"
|
Self::Replace { span, text } => JsChangeInner::Replace {
|
||||||
]),
|
str: smallvec![text.as_str()],
|
||||||
Self::Replace { text, .. } => JsChangeInner::Replace(smallvec![text.as_str()]),
|
},
|
||||||
Self::Delete { .. } => JsChangeInner::Replace(smallvec![]),
|
Self::Delete { span } => JsChangeInner::Replace { str: smallvec![""] },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for Rewrite {
|
impl PartialOrd for JsChange {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
Some(self.cmp(other))
|
Some(self.cmp(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ord for Rewrite {
|
impl Ord for JsChange {
|
||||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
self.get_span().start.cmp(&other.get_span().start)
|
self.get_span().start.cmp(&other.get_span().start)
|
||||||
}
|
}
|
||||||
|
@ -210,17 +343,8 @@ impl Ord for Rewrite {
|
||||||
type Changes<'a> = SmallVec<[&'a str; 8]>;
|
type Changes<'a> = SmallVec<[&'a str; 8]>;
|
||||||
|
|
||||||
enum JsChangeInner<'a> {
|
enum JsChangeInner<'a> {
|
||||||
Wrap {
|
Insert { loc: u32, str: Changes<'a> },
|
||||||
/// Changes to add before span
|
Replace { str: Changes<'a> },
|
||||||
before: Changes<'a>,
|
|
||||||
/// Span to add in between
|
|
||||||
inner: &'a Span,
|
|
||||||
/// Changes to add after span
|
|
||||||
after: Changes<'a>,
|
|
||||||
},
|
|
||||||
Replace {
|
|
||||||
str: Changes<'a>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct JsChangeResult {
|
pub(crate) struct JsChangeResult {
|
||||||
|
@ -229,7 +353,7 @@ pub(crate) struct JsChangeResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct JsChanges {
|
pub(crate) struct JsChanges {
|
||||||
pub inner: Vec<Rewrite>,
|
pub inner: Vec<JsChange>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsChanges {
|
impl JsChanges {
|
||||||
|
@ -238,7 +362,7 @@ impl JsChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, change: Rewrite) {
|
pub fn add(&mut self, change: Rewrite) {
|
||||||
self.inner.push(change);
|
self.inner.extend(change.into_inner().into_iter());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform<E>(&mut self, js: &str, cfg: &Config<E>) -> Result<JsChangeResult, RewriterError>
|
pub fn perform<E>(&mut self, js: &str, cfg: &Config<E>) -> Result<JsChangeResult, RewriterError>
|
||||||
|
@ -267,30 +391,13 @@ impl JsChanges {
|
||||||
|
|
||||||
let inner = change.to_inner(cfg);
|
let inner = change.to_inner(cfg);
|
||||||
match inner {
|
match inner {
|
||||||
JsChangeInner::Wrap {
|
JsChangeInner::Insert { loc, str } => {
|
||||||
before,
|
for str in str {
|
||||||
inner: wrapspan,
|
|
||||||
after,
|
|
||||||
} => {
|
|
||||||
// wrap op
|
|
||||||
for str in before {
|
|
||||||
buffer.extend_from_slice(str.as_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
let wrapstart = wrapspan.start as usize;
|
|
||||||
let wrapend = wrapspan.end as usize;
|
|
||||||
buffer.extend_from_slice(
|
|
||||||
js.get(wrapstart..wrapend)
|
|
||||||
.ok_or_else(|| RewriterError::Oob(wrapstart..wrapend))?
|
|
||||||
.as_bytes(),
|
|
||||||
);
|
|
||||||
|
|
||||||
for str in after {
|
|
||||||
buffer.extend_from_slice(str.as_bytes());
|
buffer.extend_from_slice(str.as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JsChangeInner::Replace(list) => {
|
JsChangeInner::Replace { str } => {
|
||||||
for str in list {
|
for str in str {
|
||||||
buffer.extend_from_slice(str.as_bytes());
|
buffer.extend_from_slice(str.as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use cfg::Config;
|
use cfg::Config;
|
||||||
use changes::{Rewrite, JsChangeResult, JsChanges};
|
use changes::{JsChangeResult, JsChanges, Rewrite};
|
||||||
use oxc::{
|
use oxc::{
|
||||||
allocator::Allocator,
|
allocator::Allocator,
|
||||||
ast::Visit,
|
ast::Visit,
|
||||||
|
@ -18,8 +18,8 @@ mod visitor;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum RewriterError {
|
pub enum RewriterError {
|
||||||
#[error("oxc panicked in parser")]
|
#[error("oxc panicked in parser: {0:?}")]
|
||||||
OxcPanicked,
|
OxcPanicked(Vec<OxcDiagnostic>),
|
||||||
#[error("out of bounds while applying range: {0:?})")]
|
#[error("out of bounds while applying range: {0:?})")]
|
||||||
Oob(Range<usize>),
|
Oob(Range<usize>),
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ pub struct RewriteResult {
|
||||||
pub js: Vec<u8>,
|
pub js: Vec<u8>,
|
||||||
pub sourcemap: Vec<u8>,
|
pub sourcemap: Vec<u8>,
|
||||||
pub errors: Vec<OxcDiagnostic>,
|
pub errors: Vec<OxcDiagnostic>,
|
||||||
pub changes: Vec<Rewrite>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rewrite<E>(js: &str, config: Config<E>) -> Result<RewriteResult, RewriterError>
|
pub fn rewrite<E>(js: &str, config: Config<E>) -> Result<RewriteResult, RewriterError>
|
||||||
|
@ -48,7 +47,7 @@ where
|
||||||
.parse();
|
.parse();
|
||||||
|
|
||||||
if ret.panicked {
|
if ret.panicked {
|
||||||
return Err(RewriterError::OxcPanicked);
|
return Err(RewriterError::OxcPanicked(ret.errors));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut visitor = Visitor {
|
let mut visitor = Visitor {
|
||||||
|
@ -62,12 +61,10 @@ where
|
||||||
} = visitor;
|
} = visitor;
|
||||||
|
|
||||||
let JsChangeResult { js, sourcemap } = jschanges.perform(js, &config)?;
|
let JsChangeResult { js, sourcemap } = jschanges.perform(js, &config)?;
|
||||||
let JsChanges { inner: changes } = jschanges;
|
|
||||||
|
|
||||||
Ok(RewriteResult {
|
Ok(RewriteResult {
|
||||||
js,
|
js,
|
||||||
sourcemap,
|
sourcemap,
|
||||||
errors: ret.errors,
|
errors: ret.errors,
|
||||||
changes,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue