Skip to content

Commit 7f35a85

Browse files
committed
[core][rewriter] dpsc: add rest cleaning rewrites
1 parent b9899df commit 7f35a85

File tree

10 files changed

+71
-15
lines changed

10 files changed

+71
-15
lines changed

rewriter/js/src/cfg.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub struct Config {
1919
pub wrapfn: String,
2020
pub wrappropertybase: String,
2121
pub wrappropertyfn: String,
22+
pub cleanrestfn: String,
2223
pub importfn: String,
2324
pub rewritefn: String,
2425
pub setrealmfn: String,

rewriter/js/src/changes.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ pub enum JsChangeType<'alloc: 'data, 'data> {
4444
ident: Atom<'data>,
4545
},
4646

47+
WrapObjectAssignmentLeft {
48+
restids: Vec<Atom<'data>>,
49+
},
50+
4751
/// insert `${cfg.setrealmfn}({}).`
4852
SetRealmFn,
4953
/// insert `$scramerr(ident);`
@@ -128,7 +132,14 @@ impl<'alloc: 'data, 'data> Transform<'data> for JsChange<'alloc, 'data> {
128132
Ty::RebindProperty { ident } => {
129133
LL::replace(transforms![&cfg.wrappropertybase, ident, ":", ident])
130134
}
131-
135+
Ty::WrapObjectAssignmentLeft { restids } => {
136+
let mut steps = String::new();
137+
for id in restids {
138+
steps.push_str(&format!("{}({}),", &cfg.cleanrestfn, id.as_str()));
139+
}
140+
let steps: &'static str = Box::leak(steps.into_boxed_str());
141+
LL::insert(transforms!["((t)=>(", &steps, "t))("])
142+
}
132143
Ty::SetRealmFn => LL::insert(transforms![&cfg.setrealmfn, "({})."]),
133144
Ty::ScramErrFn { ident } => LL::insert(transforms!["$scramerr(", ident, ");"]),
134145
Ty::ScramitizeFn => LL::insert(transforms![" $scramitize("]),

rewriter/js/src/rewrite.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ pub(crate) enum RewriteType<'alloc: 'data, 'data> {
3737
ident: Atom<'data>,
3838
},
3939

40+
WrapObjectAssignment {
41+
restids: Vec<Atom<'data>>,
42+
},
43+
4044
/// `cfg.wrapprop({})`
4145
WrapProperty,
4246

@@ -119,6 +123,16 @@ impl<'alloc: 'data, 'data> RewriteType<'alloc, 'data> {
119123
change!(span!(start), WrapPropertyLeft),
120124
change!(span!(end), WrapPropertyRight),
121125
],
126+
Self::WrapObjectAssignment { restids } => smallvec![
127+
change!(span!(start), WrapObjectAssignmentLeft { restids }),
128+
change!(
129+
span!(end),
130+
ClosingParen {
131+
semi: false,
132+
replace: false
133+
}
134+
)
135+
],
122136
Self::SetRealmFn => smallvec![change!(span, SetRealmFn)],
123137
Self::ImportFn => smallvec![change!(span, ImportFn)],
124138
Self::MetaFn => smallvec![change!(span, MetaFn)],

rewriter/js/src/visitor.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ use oxc::{
44
allocator::{Allocator, StringBuilder},
55
ast::ast::{
66
AssignmentExpression, AssignmentTarget, AssignmentTargetMaybeDefault,
7-
AssignmentTargetProperty, BindingPattern, BindingPatternKind, BindingProperty,
8-
CallExpression, ComputedMemberExpression, DebuggerStatement, ExportAllDeclaration,
9-
ExportNamedDeclaration, Expression, FunctionBody, IdentifierReference, ImportDeclaration,
10-
ImportExpression, MemberExpression, MetaProperty, NewExpression, ObjectAssignmentTarget,
11-
ObjectExpression, ObjectPattern, ObjectPropertyKind, PrivateIdentifier, PropertyKey,
12-
ReturnStatement, SimpleAssignmentTarget, StringLiteral, ThisExpression, UnaryExpression,
13-
UnaryOperator, UpdateExpression,
7+
AssignmentTargetProperty, AssignmentTargetPropertyIdentifier, BindingPattern,
8+
BindingPatternKind, BindingProperty, CallExpression, ComputedMemberExpression,
9+
DebuggerStatement, ExportAllDeclaration, ExportNamedDeclaration, Expression, FunctionBody,
10+
IdentifierReference, ImportDeclaration, ImportExpression, MemberExpression, MetaProperty,
11+
NewExpression, ObjectAssignmentTarget, ObjectExpression, ObjectPattern, ObjectPropertyKind,
12+
PrivateIdentifier, PropertyKey, ReturnStatement, SimpleAssignmentTarget, StringLiteral,
13+
ThisExpression, UnaryExpression, UnaryOperator, UpdateExpression,
1414
},
1515
ast_visit::{Visit, walk},
1616
span::{Atom, GetSpan, Span},
@@ -104,10 +104,21 @@ where
104104
}
105105
}
106106

107-
fn recurse_object_assignment_target(&mut self, s: &ObjectAssignmentTarget<'data>) {
108-
if s.rest.is_some() {
109-
// infeasible to rewrite :(
110-
eprintln!("cannot rewrite rest parameters");
107+
fn recurse_object_assignment_target(
108+
&mut self,
109+
s: &ObjectAssignmentTarget<'data>,
110+
restids: &mut Vec<Atom<'data>>,
111+
) {
112+
if let Some(r) = &s.rest {
113+
// { ...rest } = self;
114+
match &r.target {
115+
AssignmentTarget::AssignmentTargetIdentifier(i) => {
116+
// keep track of the name so we can clean it later
117+
// i don't really care about the rest being `location` here, if someone wants to redirect to `https://proxy.com/[Object object]` they can
118+
restids.push(i.name);
119+
}
120+
_ => panic!("what?"),
121+
}
111122
return;
112123
}
113124
for prop in &s.properties {
@@ -168,7 +179,7 @@ where
168179
walk::walk_expression(self, &d.init);
169180
}
170181
AssignmentTargetMaybeDefault::ObjectAssignmentTarget(p) => {
171-
self.recurse_object_assignment_target(p);
182+
self.recurse_object_assignment_target(p, restids);
172183
}
173184
_ => {}
174185
}
@@ -487,7 +498,13 @@ where
487498
walk::walk_expression(self, &s.expression);
488499
}
489500
AssignmentTarget::ObjectAssignmentTarget(o) => {
490-
self.recurse_object_assignment_target(o);
501+
let mut restids: Vec<Atom<'data>> = Vec::new();
502+
self.recurse_object_assignment_target(o, &mut restids);
503+
504+
if restids.len() > 0 {
505+
self.jschanges
506+
.add(rewrite!(it.span, WrapObjectAssignment { restids }));
507+
}
491508
return;
492509
}
493510
_ => {}

rewriter/native/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub struct RewriterOptions {
2929
wrappropertybase: String,
3030
#[clap(long, default_value = "$prop")]
3131
wrappropertyfn: String,
32+
#[clap(long, default_value = "$clean")]
33+
cleanrestfn: String,
3234
#[clap(long, default_value = "$import")]
3335
importfn: String,
3436
#[clap(long, default_value = "$rewrite")]

rewriter/native/src/rewriter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ impl NativeRewriter {
5454
wrapfn: cfg.wrapfn.clone(),
5555
wrappropertybase: cfg.wrappropertybase.clone(),
5656
wrappropertyfn: cfg.wrappropertyfn.clone(),
57+
cleanrestfn: cfg.cleanrestfn.clone(),
5758
importfn: cfg.importfn.clone(),
5859
rewritefn: cfg.rewritefn.clone(),
5960
metafn: cfg.metafn.clone(),

rewriter/wasm/src/jsr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fn get_config(scramjet: &Object) -> Result<Config> {
5151

5252
wrappropertybase: get_str(globals, "wrappropertybase")?,
5353
wrappropertyfn: get_str(globals, "wrappropertyfn")?,
54+
cleanrestfn: get_str(globals, "cleanrestfn")?,
5455
wrapfn: get_str(globals, "wrapfn")?,
5556
importfn: get_str(globals, "importfn")?,
5657
rewritefn: get_str(globals, "rewritefn")?,

src/client/shared/wrap.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ export default function (client: ScramjetClient, self: typeof globalThis) {
6666
configurable: false,
6767
enumerable: false,
6868
});
69-
console.log(config.globals.wrappropertybase);
69+
Object.defineProperty(self, config.globals.cleanrestfn, {
70+
value: function (obj) {
71+
// TODO
72+
},
73+
writable: false,
74+
configurable: false,
75+
enumerable: false,
76+
});
7077

7178
Object.defineProperty(
7279
self.Object.prototype,

src/controller/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export class ScramjetController {
2020
wrapfn: "$scramjet$wrap",
2121
wrappropertybase: "$scramjet__",
2222
wrappropertyfn: "$scramjet$prop",
23+
cleanrestfn: "$scramjet$clean",
2324
trysetfn: "$scramjet$tryset",
2425
importfn: "$scramjet$import",
2526
rewritefn: "$scramjet$rewrite",

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface ScramjetConfig {
2222
wrapfn: string;
2323
wrappropertybase: string;
2424
wrappropertyfn: string;
25+
cleanrestfn: string;
2526
trysetfn: string;
2627
importfn: string;
2728
rewritefn: string;

0 commit comments

Comments
 (0)