mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-13 06:20:02 -04:00
scramtag has offset now
This commit is contained in:
parent
1343900f7c
commit
b2007a2f58
2 changed files with 104 additions and 48 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue