scramtag has offset now

This commit is contained in:
Toshit Chawda 2024-12-18 16:04:24 -08:00
parent 1343900f7c
commit b2007a2f58
No known key found for this signature in database
GPG key ID: 91480ED99E2B3D9D
2 changed files with 104 additions and 48 deletions

View file

@ -2,7 +2,7 @@ use std::cmp::Ordering;
use oxc::{ use oxc::{
ast::ast::AssignmentOperator, ast::ast::AssignmentOperator,
span::{CompactStr, Span}, span::{format_compact_str, CompactStr, Span},
}; };
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
@ -63,7 +63,6 @@ pub(crate) enum Rewrite {
}, },
SourceTag { SourceTag {
span: Span, span: Span,
tagname: String,
}, },
// don't use for anything static, only use for stuff like rewriteurl // don't use for anything static, only use for stuff like rewriteurl
@ -163,13 +162,61 @@ impl Rewrite {
span: Span::new(span.end, span.end) span: Span::new(span.end, span.end)
}], }],
// maps to insert // maps to insert
Self::SourceTag { tagname, span } => smallvec![JsChange::SourceTag { span, tagname }], Self::SourceTag { span } => smallvec![JsChange::SourceTag { span }],
Self::Replace { text, span } => smallvec![JsChange::Replace { span, text }], Self::Replace { text, span } => smallvec![JsChange::Replace { span, text }],
Self::Delete { span } => smallvec![JsChange::Delete { span }], Self::Delete { span } => smallvec![JsChange::Delete { span }],
} }
} }
} }
enum Change<'a> {
Str(&'a str),
Number(usize),
}
impl<'a> From<&'a str> for Change<'a> {
fn from(value: &'a str) -> Self {
Self::Str(value)
}
}
impl<'a> From<&'a CompactStr> for Change<'a> {
fn from(value: &'a CompactStr) -> Self {
Self::Str(value.as_str())
}
}
impl<'a> From<&'a String> for Change<'a> {
fn from(value: &'a String) -> Self {
Self::Str(value.as_str())
}
}
impl<'a> From<&'a AssignmentOperator> for Change<'a> {
fn from(value: &'a AssignmentOperator) -> Self {
Self::Str(value.as_str())
}
}
impl From<usize> for Change<'static> {
fn from(value: usize) -> Self {
Self::Number(value)
}
}
macro_rules! changes {
[$($change:expr),+] => {
smallvec![$(Change::from($change)),+]
};
}
type Changes<'a> = SmallVec<[Change<'a>; 8]>;
enum JsChangeInner<'a> {
Insert { loc: u32, str: Changes<'a> },
Replace { str: Changes<'a> },
}
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
enum JsChange { enum JsChange {
/// insert `${cfg.wrapfn}(` /// insert `${cfg.wrapfn}(`
@ -187,7 +234,7 @@ enum JsChange {
/// insert `: ${cfg.wrapfn}(ident)` /// insert `: ${cfg.wrapfn}(ident)`
ShorthandObj { span: Span, ident: CompactStr }, ShorthandObj { span: Span, ident: CompactStr },
/// insert scramtag /// insert scramtag
SourceTag { span: Span, tagname: String }, SourceTag { span: Span },
/// replace span with `(${cfg.importfn}("${cfg.base}"))` /// replace span with `(${cfg.importfn}("${cfg.base}"))`
ImportFn { span: Span }, ImportFn { span: Span },
@ -235,7 +282,7 @@ impl JsChange {
} }
} }
fn to_inner<'a, E>(&'a self, cfg: &'a Config<E>) -> JsChangeInner<'a> fn to_inner<'a, E>(&'a self, cfg: &'a Config<E>, offset: usize) -> JsChangeInner<'a>
where where
E: Fn(String) -> String, E: Fn(String) -> String,
E: Clone, E: Clone,
@ -245,85 +292,79 @@ impl JsChange {
if *extra { if *extra {
JsChangeInner::Insert { JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec!["(", cfg.wrapfn.as_str(), "("], str: changes!["(", &cfg.wrapfn, "("],
} }
} else { } else {
JsChangeInner::Insert { JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec![cfg.wrapfn.as_str(), "("], str: changes![&cfg.wrapfn, "("],
} }
} }
} }
Self::SetRealmFn { span } => JsChangeInner::Insert { Self::SetRealmFn { span } => JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec![cfg.setrealmfn.as_str(), "({})."], str: changes![&cfg.setrealmfn, "({})."],
}, },
Self::WrapThisFn { span } => JsChangeInner::Insert { Self::WrapThisFn { span } => JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec![cfg.wrapthisfn.as_str(), "("], str: changes![&cfg.wrapthisfn, "("],
}, },
Self::ScramErrFn { span, ident } => JsChangeInner::Insert { Self::ScramErrFn { span, ident } => JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec!["$scramerr(", ident.as_str(), ");"], str: changes!["$scramerr(", ident, ");"],
}, },
Self::ScramitizeFn { span } => JsChangeInner::Insert { Self::ScramitizeFn { span } => JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec![" $scramitize("], str: changes![" $scramitize("],
}, },
Self::EvalRewriteFn { .. } => JsChangeInner::Replace { Self::EvalRewriteFn { .. } => JsChangeInner::Replace {
str: smallvec!["eval(", cfg.rewritefn.as_str(), "("], str: changes!["eval(", &cfg.rewritefn, "("],
}, },
Self::ShorthandObj { span, ident } => JsChangeInner::Insert { Self::ShorthandObj { span, ident } => JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec![":", cfg.wrapfn.as_str(), "(", ident.as_str(), ")"], str: changes![":", &cfg.wrapfn, "(", ident, ")"],
}, },
Self::SourceTag { span, tagname } => JsChangeInner::Insert { Self::SourceTag { span } => JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec![ str: changes![
"/*scramtag ", "/*scramtag ",
tagname.as_str(), span.start as usize + offset,
" ", " ",
cfg.sourcetag.as_str(), &cfg.sourcetag,
"*/" "*/"
], ],
}, },
Self::ImportFn { .. } => JsChangeInner::Replace { Self::ImportFn { .. } => JsChangeInner::Replace {
str: smallvec!["(", cfg.importfn.as_str(), "(\"", cfg.base.as_str(), "\"))"], str: changes!["(", &cfg.importfn, "(\"", &cfg.base, "\"))"],
}, },
Self::MetaFn { .. } => JsChangeInner::Replace { Self::MetaFn { .. } => JsChangeInner::Replace {
str: smallvec![cfg.metafn.as_str(), "(\"", cfg.base.as_str()], str: changes![&cfg.metafn, "(\"", &cfg.base],
}, },
Self::AssignmentLeft { name, op, .. } => JsChangeInner::Replace { Self::AssignmentLeft { name, op, .. } => JsChangeInner::Replace {
str: smallvec![ str: changes![
"((t)=>$scramjet$tryset(", "((t)=>$scramjet$tryset(",
name.as_str(), name,
",\"", ",\"",
op.as_str(), op,
"\",t)||(", "\",t)||(",
name.as_str(), name,
op.as_str(), op,
"t))(" "t))("
], ],
}, },
Self::ReplaceClosingParen { .. } => JsChangeInner::Replace { Self::ReplaceClosingParen { .. } => JsChangeInner::Replace { str: changes![")"] },
str: smallvec![")"],
},
Self::ClosingParen { span, semi } => JsChangeInner::Insert { Self::ClosingParen { span, semi } => JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: if *semi { str: if *semi { changes![");"] } else { changes![")"] },
smallvec![");"]
} else {
smallvec![")"]
},
}, },
Self::DoubleClosingParen { span } => JsChangeInner::Insert { Self::DoubleClosingParen { span } => JsChangeInner::Insert {
loc: span.start, loc: span.start,
str: smallvec!["))"], str: changes!["))"],
}, },
Self::Replace { text, .. } => JsChangeInner::Replace { Self::Replace { text, .. } => JsChangeInner::Replace {
str: smallvec![text.as_str()], str: changes![text],
}, },
Self::Delete { .. } => JsChangeInner::Replace { str: smallvec![""] }, Self::Delete { .. } => JsChangeInner::Replace { str: changes![""] },
} }
} }
} }
@ -347,13 +388,6 @@ impl Ord for JsChange {
} }
} }
type Changes<'a> = SmallVec<[&'a str; 8]>;
enum JsChangeInner<'a> {
Insert { loc: u32, str: Changes<'a> },
Replace { str: Changes<'a> },
}
pub(crate) struct JsChangeResult { pub(crate) struct JsChangeResult {
pub js: Vec<u8>, pub js: Vec<u8>,
pub sourcemap: Vec<u8>, pub sourcemap: Vec<u8>,
@ -390,6 +424,17 @@ impl JsChanges {
.ok_or_else(|| RewriterError::Oob(($range).start, ($range).end))? .ok_or_else(|| RewriterError::Oob(($range).start, ($range).end))?
}; };
} }
macro_rules! eval {
($change:expr) => {
match $change {
Change::Str(x) => buffer.extend_from_slice(x.as_bytes()),
Change::Number(x) => {
let x = format_compact_str!("{}", x);
buffer.extend_from_slice(x.as_bytes());
}
}
};
}
let mut map = Vec::with_capacity(js.len() * 2); let mut map = Vec::with_capacity(js.len() * 2);
map.extend_from_slice(&(self.inner.len() as u32).to_le_bytes()); map.extend_from_slice(&(self.inner.len() as u32).to_le_bytes());
@ -403,11 +448,12 @@ impl JsChanges {
buffer.extend_from_slice(tryget!(offset..start).as_bytes()); buffer.extend_from_slice(tryget!(offset..start).as_bytes());
let inner = change.to_inner(cfg); match change.to_inner(cfg, offset) {
match inner {
JsChangeInner::Insert { loc, str } => { JsChangeInner::Insert { loc, str } => {
// INSERT op // INSERT op
map.push(0); map.push(0);
// offset
map.extend_from_slice(&(offset as u32).to_le_bytes());
// start // start
map.extend_from_slice(&loc.to_le_bytes()); map.extend_from_slice(&loc.to_le_bytes());
// size // size
@ -416,13 +462,15 @@ impl JsChanges {
let loc = loc as usize; let loc = loc as usize;
buffer.extend_from_slice(tryget!(start..loc).as_bytes()); buffer.extend_from_slice(tryget!(start..loc).as_bytes());
for str in str { for str in str {
buffer.extend_from_slice(str.as_bytes()); eval!(str);
} }
buffer.extend_from_slice(tryget!(loc..end).as_bytes()); buffer.extend_from_slice(tryget!(loc..end).as_bytes());
} }
JsChangeInner::Replace { str } => { JsChangeInner::Replace { str } => {
// REPLACE op // REPLACE op
map.push(1); map.push(1);
// offset
map.extend_from_slice(&(offset as u32).to_le_bytes());
// start // start
map.extend_from_slice(&span.start.to_le_bytes()); map.extend_from_slice(&span.start.to_le_bytes());
// end // end
@ -431,7 +479,7 @@ impl JsChanges {
map.extend_from_slice(tryget!(start..end).as_bytes()); map.extend_from_slice(tryget!(start..end).as_bytes());
for str in str { for str in str {
buffer.extend_from_slice(str.as_bytes()); eval!(str);
} }
} }
} }

View file

@ -9,6 +9,8 @@ enum RewriteType {
type Rewrite = type Rewrite =
| { | {
type: RewriteType.Insert; type: RewriteType.Insert;
// offset before this rewrite
offset: number;
// start of insertion // start of insertion
start: number; start: number;
// size of insertion // size of insertion
@ -16,6 +18,8 @@ type Rewrite =
} }
| { | {
type: RewriteType.Replace; type: RewriteType.Replace;
// offset before this rewrite
offset: number;
// start of replacement // start of replacement
start: number; start: number;
// end of replacement // end of replacement
@ -46,13 +50,17 @@ export default function (client: ScramjetClient, self: Self) {
cursor += 1; cursor += 1;
if (type == RewriteType.Insert) { if (type == RewriteType.Insert) {
const offset = view.getUint32(cursor, true);
cursor += 4;
const start = view.getUint32(cursor, true); const start = view.getUint32(cursor, true);
cursor += 4; cursor += 4;
const size = view.getUint32(cursor, true); const size = view.getUint32(cursor, true);
cursor += 4; cursor += 4;
rewrites.push({ type, start, size }); rewrites.push({ type, offset, start, size });
} else if (type == RewriteType.Replace) { } else if (type == RewriteType.Replace) {
const offset = view.getUint32(cursor, true);
cursor += 4;
const start = view.getUint32(cursor, true); const start = view.getUint32(cursor, true);
cursor += 4; cursor += 4;
const end = view.getUint32(cursor, true); const end = view.getUint32(cursor, true);
@ -60,7 +68,7 @@ export default function (client: ScramjetClient, self: Self) {
const str = decoder.decode(sourcemap.subarray(start, end)); const str = decoder.decode(sourcemap.subarray(start, end));
rewrites.push({ type, start, end, str }); rewrites.push({ type, offset, start, end, str });
} }
} }