Skip to content

Commit f8394c6

Browse files
authored
fix: fix wrong js generation (#118)
1 parent 59ff242 commit f8394c6

File tree

5 files changed

+106
-50
lines changed

5 files changed

+106
-50
lines changed

src/optimizer/core/src/collector.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, HashSet};
22

33
use swc_atoms::{js_word, JsWord};
44
use swc_ecmascript::ast;
5-
use swc_ecmascript::visit::{noop_visit_type, Visit, VisitWith};
5+
use swc_ecmascript::visit::{noop_visit_type, visit_expr, visit_stmt, Visit, VisitWith};
66

77
macro_rules! id {
88
($ident: expr) => {
@@ -410,13 +410,13 @@ impl Visit for HookCollect {
410410

411411
fn visit_expr(&mut self, node: &ast::Expr) {
412412
self.expr_ctxt.push(ExprOrSkip::Expr);
413-
swc_ecmascript::visit::visit_expr(self, node);
413+
visit_expr(self, node);
414414
self.expr_ctxt.pop();
415415
}
416416

417417
fn visit_stmt(&mut self, node: &ast::Stmt) {
418418
self.expr_ctxt.push(ExprOrSkip::Skip);
419-
swc_ecmascript::visit::visit_stmt(self, node);
419+
visit_stmt(self, node);
420420
self.expr_ctxt.pop();
421421
}
422422

src/optimizer/core/src/parse.rs

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ use swc_ecmascript::parser::{EsConfig, PResult, Parser, StringInput, Syntax, TsC
2828
use swc_ecmascript::transforms::{
2929
fixer,
3030
hygiene::{self, hygiene_with_config},
31-
resolver_with_mark,
31+
optimization::simplify,
32+
pass, react, resolver_with_mark, typescript,
3233
};
33-
use swc_ecmascript::transforms::{optimization::simplify, pass, react, typescript};
34-
use swc_ecmascript::visit::FoldWith;
34+
use swc_ecmascript::visit::{FoldWith, VisitMutWith};
3535

3636
#[derive(Debug, Serialize, Deserialize)]
3737
#[serde(rename_all = "camelCase")]
@@ -151,12 +151,17 @@ pub fn transform_code(config: TransformCodeOptions) -> Result<TransformOutput, a
151151
};
152152

153153
let collect = global_collect(&main_module);
154-
let top_level_mark = Mark::fresh(Mark::root());
154+
let global_mark = Mark::fresh(Mark::root());
155+
155156
let mut hooks: Vec<Hook> = vec![];
157+
let mut main_module = main_module;
158+
159+
main_module.visit_mut_with(&mut resolver_with_mark(global_mark));
160+
156161
let mut main_module = {
157162
let mut passes = chain!(
158163
pass::Optional::new(
159-
typescript::strip(top_level_mark),
164+
typescript::strip(global_mark),
160165
transpile && is_type_script && !is_jsx
161166
),
162167
pass::Optional::new(
@@ -168,7 +173,7 @@ pub fn transform_code(config: TransformCodeOptions) -> Result<TransformOutput, a
168173
..Default::default()
169174
},
170175
Some(&comments),
171-
top_level_mark,
176+
global_mark,
172177
),
173178
transpile && is_type_script && is_jsx
174179
),
@@ -177,7 +182,7 @@ pub fn transform_code(config: TransformCodeOptions) -> Result<TransformOutput, a
177182
Lrc::clone(&source_map),
178183
Some(&comments),
179184
react_options,
180-
top_level_mark
185+
global_mark
181186
),
182187
transpile && is_jsx
183188
),
@@ -188,44 +193,40 @@ pub fn transform_code(config: TransformCodeOptions) -> Result<TransformOutput, a
188193
Some(&comments),
189194
&mut hooks
190195
),
191-
pass::Optional::new(
192-
resolver_with_mark(top_level_mark),
193-
config.minify != MinifyMode::None
194-
),
195-
pass::Optional::new(
196-
simplify::simplifier(Default::default()),
197-
config.minify != MinifyMode::None
198-
)
199196
);
200197
main_module.fold_with(&mut passes)
201198
};
202199

203-
if config.minify == MinifyMode::Minify {
204-
main_module = optimize(
205-
main_module,
206-
Lrc::clone(&source_map),
207-
Some(&comments),
208-
None,
209-
&MinifyOptions {
210-
compress: Some(CompressOptions {
211-
..CompressOptions::default()
212-
}),
213-
mangle: Some(MangleOptions {
214-
top_level: true,
215-
..MangleOptions::default()
216-
}),
217-
rename: true,
218-
wrap: false,
219-
enclose: false,
220-
},
221-
&ExtraOptions { top_level_mark },
222-
);
200+
if config.minify != MinifyMode::None {
201+
let top_level_mark = Mark::fresh(Mark::root());
202+
main_module.visit_mut_with(&mut resolver_with_mark(top_level_mark));
203+
main_module =
204+
main_module.fold_with(&mut simplify::simplifier(Default::default()));
205+
206+
if config.minify == MinifyMode::Minify {
207+
main_module = optimize(
208+
main_module,
209+
Lrc::clone(&source_map),
210+
Some(&comments),
211+
None,
212+
&MinifyOptions {
213+
compress: Some(CompressOptions {
214+
..CompressOptions::default()
215+
}),
216+
mangle: Some(MangleOptions {
217+
top_level: true,
218+
..MangleOptions::default()
219+
}),
220+
rename: true,
221+
wrap: false,
222+
enclose: false,
223+
},
224+
&ExtraOptions { top_level_mark },
225+
);
226+
}
223227

224-
main_module = main_module
225-
.fold_with(&mut hygiene_with_config(hygiene::Config {
226-
..Default::default()
227-
}))
228-
.fold_with(&mut fixer(None));
228+
main_module.visit_mut_with(&mut hygiene_with_config(Default::default()));
229+
main_module.visit_mut_with(&mut fixer(None));
229230
}
230231

231232
let mut hooks_analysis: Vec<HookAnalysis> = Vec::with_capacity(hooks.len());
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
source: src/optimizer/core/src/test.rs
3+
expression: output
4+
5+
---
6+
==INPUT==
7+
8+
9+
export const cache = patternCache[cacheKey] || (patternCache[cacheKey]={});
10+
11+
============================= project/test.tsx ==
12+
13+
export const cache = patternCache[cacheKey] || (patternCache[cacheKey] = {
14+
});
15+
16+
== HOOKS ==
17+
18+
[]
19+
20+
== DIAGNOSTICS ==
21+
22+
[]

src/optimizer/core/src/test.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const Header = qComponent({
1616
});
1717
"#,
1818
EntryStrategy::Hook,
19+
MinifyMode::Simplify,
1920
false,
2021
);
2122
}
@@ -35,6 +36,7 @@ export const Header = qComponent({
3536
});
3637
"#,
3738
EntryStrategy::Hook,
39+
MinifyMode::Simplify,
3840
false,
3941
);
4042
}
@@ -57,6 +59,7 @@ export const App = () => {
5759
});
5860
"#,
5961
EntryStrategy::Hook,
62+
MinifyMode::Simplify,
6063
false,
6164
);
6265
}
@@ -79,6 +82,7 @@ export function App() {
7982
}
8083
"#,
8184
EntryStrategy::Hook,
85+
MinifyMode::Simplify,
8286
false,
8387
);
8488
}
@@ -100,6 +104,7 @@ export const Header = qComponent({
100104
});
101105
"#,
102106
EntryStrategy::Hook,
107+
MinifyMode::Simplify,
103108
false,
104109
);
105110
}
@@ -112,6 +117,7 @@ fn example_6() {
112117
export const sym1 = qHook((ctx) => console.log("1"));
113118
"#,
114119
EntryStrategy::Hook,
120+
MinifyMode::Simplify,
115121
false,
116122
);
117123
}
@@ -141,6 +147,7 @@ const App = qComponent({
141147
})
142148
});"#,
143149
EntryStrategy::Hook,
150+
MinifyMode::Simplify,
144151
false,
145152
);
146153
}
@@ -164,6 +171,7 @@ const Header = qComponent({
164171
});
165172
"#,
166173
EntryStrategy::Hook,
174+
MinifyMode::Simplify,
167175
false,
168176
);
169177
}
@@ -186,6 +194,7 @@ const Header = qHook((decl1, {decl2}, [decl3]) => {
186194
});
187195
"#,
188196
EntryStrategy::Hook,
197+
MinifyMode::Simplify,
189198
false,
190199
);
191200
}
@@ -215,6 +224,7 @@ const Header = qHook((decl1, {decl2}, [decl3]) => {
215224
});
216225
"#,
217226
EntryStrategy::Hook,
227+
MinifyMode::Simplify,
218228
false,
219229
);
220230
}
@@ -247,6 +257,7 @@ export const App = qComponent({
247257
});
248258
"#,
249259
EntryStrategy::Single,
260+
MinifyMode::Simplify,
250261
false,
251262
);
252263
}
@@ -262,6 +273,7 @@ export const Header = qComponent({
262273
263274
"#,
264275
EntryStrategy::Single,
276+
MinifyMode::Simplify,
265277
false,
266278
);
267279
}
@@ -277,6 +289,20 @@ export const Header = qComponent({
277289
278290
"#,
279291
EntryStrategy::Single,
292+
MinifyMode::Simplify,
293+
false,
294+
);
295+
}
296+
297+
#[test]
298+
fn issue_117() {
299+
test_input(
300+
"project/test.tsx",
301+
r#"
302+
export const cache = patternCache[cacheKey] || (patternCache[cacheKey]={});
303+
"#,
304+
EntryStrategy::Single,
305+
MinifyMode::Simplify,
280306
false,
281307
);
282308
}
@@ -311,16 +337,22 @@ export const Header = qComponent({
311337
// }
312338
// }
313339

314-
fn test_input(filename: &str, code: &str, entry_strategy: EntryStrategy, _print_ast: bool) {
340+
fn test_input(
341+
filename: &str,
342+
code: &str,
343+
entry_strategy: EntryStrategy,
344+
minify: MinifyMode,
345+
transpile: bool,
346+
) {
315347
let res = transform_modules(TransformModulesOptions {
316348
root_dir: "/user/qwik/src/".into(),
317349
input: vec![TransformModuleInput {
318350
code: code.to_string(),
319351
path: filename.to_string(),
320352
}],
321353
source_maps: true,
322-
minify: MinifyMode::Simplify,
323-
transpile: false,
354+
minify,
355+
transpile,
324356
entry_strategy,
325357
});
326358
match res {

src/optimizer/core/src/transform.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use regex::Regex;
1010
use std::sync::{Arc, Mutex};
1111
use swc_atoms::JsWord;
1212
use swc_common::comments::{Comments, SingleThreadedComments};
13-
use swc_common::{errors::HANDLER, DUMMY_SP};
13+
use swc_common::{errors::HANDLER, Span, DUMMY_SP};
1414
use swc_ecmascript::ast;
1515
use swc_ecmascript::visit::{noop_fold_type, Fold, FoldWith};
1616

@@ -240,6 +240,7 @@ impl<'a> Fold for HookTransform<'a> {
240240
fn fold_call_expr(&mut self, node: ast::CallExpr) -> ast::CallExpr {
241241
if let ast::ExprOrSuper::Expr(expr) = &node.callee {
242242
if let ast::Expr::Ident(id) = &**expr {
243+
let qhook_span = id.span;
243244
if QCOMPONENT.eq(&id.sym) {
244245
if let Some(comments) = self.comments {
245246
comments.add_pure_comment(node.span.lo);
@@ -319,7 +320,7 @@ impl<'a> Fold for HookTransform<'a> {
319320
origin: self.path_data.path.to_string_lossy().into(),
320321
});
321322

322-
return create_inline_qhook(import_path, &symbol_name);
323+
return create_inline_qhook(import_path, &symbol_name, qhook_span);
323324
}
324325
}
325326
}
@@ -328,11 +329,11 @@ impl<'a> Fold for HookTransform<'a> {
328329
}
329330
}
330331

331-
fn create_inline_qhook(url: JsWord, symbol: &str) -> ast::CallExpr {
332+
fn create_inline_qhook(url: JsWord, symbol: &str, span: Span) -> ast::CallExpr {
332333
ast::CallExpr {
333334
callee: ast::ExprOrSuper::Expr(Box::new(ast::Expr::Ident(ast::Ident::new(
334335
QHOOK.clone(),
335-
DUMMY_SP,
336+
span,
336337
)))),
337338
span: DUMMY_SP,
338339
type_args: None,

0 commit comments

Comments
 (0)