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::{
ast::ast::AssignmentOperator,
span::{CompactStr, Span},
span::{format_compact_str, CompactStr, Span},
};
use smallvec::{smallvec, SmallVec};
@ -63,7 +63,6 @@ pub(crate) enum Rewrite {
},
SourceTag {
span: Span,
tagname: String,
},
// 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)
}],
// 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::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)]
enum JsChange {
/// insert `${cfg.wrapfn}(`
@ -187,7 +234,7 @@ enum JsChange {
/// insert `: ${cfg.wrapfn}(ident)`
ShorthandObj { span: Span, ident: CompactStr },
/// insert scramtag
SourceTag { span: Span, tagname: String },
SourceTag { span: Span },
/// replace span with `(${cfg.importfn}("${cfg.base}"))`
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
E: Fn(String) -> String,
E: Clone,
@ -245,85 +292,79 @@ impl JsChange {
if *extra {
JsChangeInner::Insert {
loc: span.start,
str: smallvec!["(", cfg.wrapfn.as_str(), "("],
str: changes!["(", &cfg.wrapfn, "("],
}
} else {
JsChangeInner::Insert {
loc: span.start,
str: smallvec![cfg.wrapfn.as_str(), "("],
str: changes![&cfg.wrapfn, "("],
}
}
}
Self::SetRealmFn { span } => JsChangeInner::Insert {
loc: span.start,
str: smallvec![cfg.setrealmfn.as_str(), "({})."],
str: changes![&cfg.setrealmfn, "({})."],
},
Self::WrapThisFn { span } => JsChangeInner::Insert {
loc: span.start,
str: smallvec![cfg.wrapthisfn.as_str(), "("],
str: changes![&cfg.wrapthisfn, "("],
},
Self::ScramErrFn { span, ident } => JsChangeInner::Insert {
loc: span.start,
str: smallvec!["$scramerr(", ident.as_str(), ");"],
str: changes!["$scramerr(", ident, ");"],
},
Self::ScramitizeFn { span } => JsChangeInner::Insert {
loc: span.start,
str: smallvec![" $scramitize("],
str: changes![" $scramitize("],
},
Self::EvalRewriteFn { .. } => JsChangeInner::Replace {
str: smallvec!["eval(", cfg.rewritefn.as_str(), "("],
str: changes!["eval(", &cfg.rewritefn, "("],
},
Self::ShorthandObj { span, ident } => JsChangeInner::Insert {
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,
str: smallvec![
str: changes![
"/*scramtag ",
tagname.as_str(),
span.start as usize + offset,
" ",
cfg.sourcetag.as_str(),
&cfg.sourcetag,
"*/"
],
},
Self::ImportFn { .. } => JsChangeInner::Replace {
str: smallvec!["(", cfg.importfn.as_str(), "(\"", cfg.base.as_str(), "\"))"],
str: changes!["(", &cfg.importfn, "(\"", &cfg.base, "\"))"],
},
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 {
str: smallvec![
str: changes![
"((t)=>$scramjet$tryset(",
name.as_str(),
name,
",\"",
op.as_str(),
op,
"\",t)||(",
name.as_str(),
op.as_str(),
name,
op,
"t))("
],
},
Self::ReplaceClosingParen { .. } => JsChangeInner::Replace {
str: smallvec![")"],
},
Self::ReplaceClosingParen { .. } => JsChangeInner::Replace { str: changes![")"] },
Self::ClosingParen { span, semi } => JsChangeInner::Insert {
loc: span.start,
str: if *semi {
smallvec![");"]
} else {
smallvec![")"]
},
str: if *semi { changes![");"] } else { changes![")"] },
},
Self::DoubleClosingParen { span } => JsChangeInner::Insert {
loc: span.start,
str: smallvec!["))"],
str: changes!["))"],
},
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 js: Vec<u8>,
pub sourcemap: Vec<u8>,
@ -390,6 +424,17 @@ impl JsChanges {
.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);
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());
let inner = change.to_inner(cfg);
match inner {
match change.to_inner(cfg, offset) {
JsChangeInner::Insert { loc, str } => {
// INSERT op
map.push(0);
// offset
map.extend_from_slice(&(offset as u32).to_le_bytes());
// start
map.extend_from_slice(&loc.to_le_bytes());
// size
@ -416,13 +462,15 @@ impl JsChanges {
let loc = loc as usize;
buffer.extend_from_slice(tryget!(start..loc).as_bytes());
for str in str {
buffer.extend_from_slice(str.as_bytes());
eval!(str);
}
buffer.extend_from_slice(tryget!(loc..end).as_bytes());
}
JsChangeInner::Replace { str } => {
// REPLACE op
map.push(1);
// offset
map.extend_from_slice(&(offset as u32).to_le_bytes());
// start
map.extend_from_slice(&span.start.to_le_bytes());
// end
@ -431,7 +479,7 @@ impl JsChanges {
map.extend_from_slice(tryget!(start..end).as_bytes());
for str in str {
buffer.extend_from_slice(str.as_bytes());
eval!(str);
}
}
}

View file

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