@tarojs/helper 3.8.0-canary.0 → 4.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/constants.d.ts +5 -3
- package/dist/constants.js +24 -22
- package/dist/constants.js.map +1 -1
- package/dist/dotenv.js.map +1 -1
- package/dist/esbuild/index.js +6 -4
- package/dist/esbuild/index.js.map +1 -1
- package/dist/npm.d.ts +2 -2
- package/dist/npm.js +6 -6
- package/dist/npm.js.map +1 -1
- package/dist/swcRegister.d.ts +0 -6
- package/dist/swcRegister.js +0 -15
- package/dist/swcRegister.js.map +1 -1
- package/dist/utils.d.ts +33 -1
- package/dist/utils.js +87 -34
- package/dist/utils.js.map +1 -1
- package/package.json +19 -15
- package/swc/plugin-compile-mode/.cargo/config +5 -0
- package/swc/plugin-compile-mode/.editorconfig +6 -0
- package/swc/plugin-compile-mode/.vscode/settings.json +3 -0
- package/swc/plugin-compile-mode/Cargo.lock +195 -260
- package/swc/plugin-compile-mode/Cargo.toml +6 -4
- package/swc/plugin-compile-mode/package.json +15 -0
- package/swc/plugin-compile-mode/src/lib.rs +21 -2
- package/swc/plugin-compile-mode/src/tests/attributes.rs +1 -32
- package/swc/plugin-compile-mode/src/tests/children.rs +86 -0
- package/swc/plugin-compile-mode/src/tests/condition.rs +8 -29
- package/swc/plugin-compile-mode/src/tests/entry.rs +1 -13
- package/swc/plugin-compile-mode/src/tests/harmony/attributes.rs +45 -0
- package/swc/plugin-compile-mode/src/tests/harmony/children.rs +74 -0
- package/swc/plugin-compile-mode/src/tests/harmony/condition.rs +79 -0
- package/swc/plugin-compile-mode/src/tests/harmony/entry.rs +67 -0
- package/swc/plugin-compile-mode/src/tests/harmony/looping.rs +62 -0
- package/swc/plugin-compile-mode/src/tests/harmony/mod.rs +45 -0
- package/swc/plugin-compile-mode/src/tests/looping.rs +1 -51
- package/swc/plugin-compile-mode/src/tests/mod.rs +11 -9
- package/swc/plugin-compile-mode/src/tests/shake.rs +1 -15
- package/swc/plugin-compile-mode/src/transform.rs +142 -134
- package/swc/plugin-compile-mode/src/transform_harmony.rs +526 -0
- package/swc/plugin-compile-mode/src/utils/constants.rs +141 -0
- package/swc/plugin-compile-mode/src/utils/harmony/components.rs +61 -0
- package/swc/plugin-compile-mode/src/utils/harmony/mod.rs +1 -0
- package/swc/plugin-compile-mode/src/utils/mod.rs +126 -15
- package/swc/plugin-compile-mode/target/wasm32-wasi/release/swc_plugin_compile_mode.wasm +0 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/attributes.rs/should_handle_events.js +8 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/attributes.rs/should_keep_static_attrs_only_in_templates.js +8 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/attributes.rs/should_turn_dynamic_attrs.js +11 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/children.rs/should_render_native_component.js +7 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/children.rs/should_render_react_component.js +7 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/children.rs/should_support_fragment.js +44 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/children.rs/should_support_render_fn.js +8 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/condition.rs/should_support_and_expr.js +14 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/condition.rs/should_support_conditional_expr.js +15 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/entry.rs/should_support_multi_compile_mode.js +10 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/attributes.rs/should_handle_events.js +183 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/attributes.rs/should_turn_dynamic_attrs.js +186 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/children.rs/should_render_react_component.js +76 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/children.rs/should_support_fragment.js +341 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/children.rs/should_support_render_fn.js +186 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/condition.rs/should_support_and_expr.js +211 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/condition.rs/should_support_complex_condition.js +244 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/condition.rs/should_support_conditional_and_unkonw_component.js +139 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/condition.rs/should_support_conditional_expr.js +344 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/entry.rs/should_support_compile_child_node.js +141 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/entry.rs/should_support_component_not_in_config.js +91 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/entry.rs/should_support_multi_compile_mode.js +209 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/entry.rs/should_support_single_compile_mode.js +66 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/looping.rs/should_loop_with_arrow_function_with_blockstmt.js +76 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/looping.rs/should_loop_with_arrow_function_with_blockstmt_and_set_parent_dynamic_id.js +89 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/harmony/looping.rs/should_loop_with_function_expr.js +86 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/looping.rs/should_loop_with_arrow_function_with_blockstmt.js +8 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/looping.rs/should_loop_with_arrow_function_with_expr.js +6 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/looping.rs/should_loop_with_function_expr.js +20 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/looping.rs/should_support_nested_loop.js +15 -0
- package/swc/plugin-compile-mode/tests/__swc_snapshots__/src/tests/shake.rs/should_static_jsx_being_shaked.js +20 -0
- package/swc/plugin-define-config/.cargo/config +5 -0
- package/swc/plugin-define-config/Cargo.lock +582 -506
- package/swc/plugin-define-config/Cargo.toml +2 -11
- package/swc/plugin-define-config/src/lib.rs +81 -128
- package/swc/plugin-define-config/target/wasm32-wasi/release/swc_plugin_define_config.wasm +0 -0
- package/swc/plugin-define-config/tests/__swc_snapshots__/src/lib.rs/module_decl_default_app.js +2 -0
- package/swc/plugin-define-config/tests/__swc_snapshots__/src/lib.rs/module_decl_default_page.js +2 -0
- package/swc/plugin-define-config/tests/__swc_snapshots__/src/lib.rs/module_exports.js +11 -0
- package/swc/plugin-define-config/tests/__swc_snapshots__/src/lib.rs/var_decl_app.js +3 -0
- package/swc/plugin-define-config/tests/__swc_snapshots__/src/lib.rs/var_decl_page.js +3 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
pub use super::get_syntax_config;
|
|
2
|
+
use swc_core::ecma::visit::{as_folder, Fold, VisitMut};
|
|
3
|
+
use crate::{
|
|
4
|
+
PluginConfig,
|
|
5
|
+
transform_harmony::*,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
mod entry;
|
|
9
|
+
mod attributes;
|
|
10
|
+
mod condition;
|
|
11
|
+
mod looping;
|
|
12
|
+
mod children;
|
|
13
|
+
|
|
14
|
+
pub fn tr () -> impl Fold + VisitMut {
|
|
15
|
+
let config = serde_json::from_str::<PluginConfig>(
|
|
16
|
+
r#"
|
|
17
|
+
{
|
|
18
|
+
"is_harmony": true,
|
|
19
|
+
"tmpl_prefix": "f0",
|
|
20
|
+
"support_events": [
|
|
21
|
+
"onLoad",
|
|
22
|
+
"onClick",
|
|
23
|
+
"onTouchEnd",
|
|
24
|
+
"onTouchMove",
|
|
25
|
+
"onTouchStart",
|
|
26
|
+
"onTouchCancel"
|
|
27
|
+
],
|
|
28
|
+
"support_components": [
|
|
29
|
+
"view",
|
|
30
|
+
"text",
|
|
31
|
+
"image"
|
|
32
|
+
],
|
|
33
|
+
"event_adapter": {
|
|
34
|
+
"onTouchEnd": "onTouch",
|
|
35
|
+
"onTouchMove": "onTouch",
|
|
36
|
+
"onTouchStart": "onTouch",
|
|
37
|
+
"onTouchCancel": "onTouch",
|
|
38
|
+
"onLoad": "onComplete"
|
|
39
|
+
}
|
|
40
|
+
}"#
|
|
41
|
+
)
|
|
42
|
+
.unwrap();
|
|
43
|
+
let visitor = TransformVisitor::new(config);
|
|
44
|
+
as_folder(visitor)
|
|
45
|
+
}
|
|
@@ -22,21 +22,6 @@ test!(
|
|
|
22
22
|
</View>
|
|
23
23
|
)
|
|
24
24
|
}
|
|
25
|
-
"#,
|
|
26
|
-
r#"
|
|
27
|
-
const TARO_TEMPLATES_f0t0 = '<template name="tmpl_0_f0t0"><view><view hover-class="{{xs.b(item.p1,\'none\')}}" wx:for="{{i.cn}}" wx:key="sid"><text>index:</text><text>{{item.cn[0].cn[0].v}}</text><text>item:</text><text>{{item.cn[1].cn[0].v}}</text></view></view></template>';
|
|
28
|
-
function Index () {
|
|
29
|
-
return <View compileMode="f0t0">
|
|
30
|
-
{list.map(function(item, index) {
|
|
31
|
-
return <View hoverClass={myClass}>
|
|
32
|
-
|
|
33
|
-
<Text>{index}</Text>
|
|
34
|
-
|
|
35
|
-
<Text>{item}</Text>
|
|
36
|
-
</View>
|
|
37
|
-
})}
|
|
38
|
-
</View>
|
|
39
|
-
}
|
|
40
25
|
"#
|
|
41
26
|
);
|
|
42
27
|
|
|
@@ -54,16 +39,6 @@ test!(
|
|
|
54
39
|
</View>
|
|
55
40
|
)
|
|
56
41
|
}
|
|
57
|
-
"#,
|
|
58
|
-
r#"
|
|
59
|
-
const TARO_TEMPLATES_f0t0 = '<template name="tmpl_0_f0t0"><view><view wx:for="{{i.cn}}" wx:key="sid">{{item.cn[0].v}}</view></view></template>';
|
|
60
|
-
function Index () {
|
|
61
|
-
return <View compileMode="f0t0">
|
|
62
|
-
{list.map(item => {
|
|
63
|
-
return <View>{item}</View>
|
|
64
|
-
})}
|
|
65
|
-
</View>
|
|
66
|
-
}
|
|
67
42
|
"#
|
|
68
43
|
);
|
|
69
44
|
|
|
@@ -79,14 +54,6 @@ test!(
|
|
|
79
54
|
</View>
|
|
80
55
|
)
|
|
81
56
|
}
|
|
82
|
-
"#,
|
|
83
|
-
r#"
|
|
84
|
-
const TARO_TEMPLATES_f0t0 = '<template name="tmpl_0_f0t0"><view><view wx:for="{{i.cn}}" wx:key="sid">{{item.cn[0].v}}</view></view></template>';
|
|
85
|
-
function Index () {
|
|
86
|
-
return <View compileMode="f0t0">
|
|
87
|
-
{list.map(item => <View>{item}</View>)}
|
|
88
|
-
</View>
|
|
89
|
-
}
|
|
90
57
|
"#
|
|
91
58
|
);
|
|
92
59
|
|
|
@@ -113,22 +80,5 @@ test!(
|
|
|
113
80
|
</View>
|
|
114
81
|
)
|
|
115
82
|
}
|
|
116
|
-
"#,
|
|
117
|
-
r#"
|
|
118
|
-
const TARO_TEMPLATES_f0t0 = '<template name="tmpl_0_f0t0"><view><view hover-class="{{xs.b(item.p1,\'none\')}}" wx:for="{{i.cn}}" wx:key="sid"><view>title: {{item.cn[0].cn[0].v}}</view><view><text selectable="{{xs.b(item.p1,!1)}}" wx:for="{{item.cn[1].cn}}" wx:key="sid">content: {{item.cn[0].v}}</text></view></view></view></template>';
|
|
119
|
-
function Index () {
|
|
120
|
-
return <View compileMode="f0t0">
|
|
121
|
-
{list.map(function(item, index) {
|
|
122
|
-
return <View hoverClass={myClass} key={index}>
|
|
123
|
-
<View>{item}</View>
|
|
124
|
-
<View>
|
|
125
|
-
{sublist.map(function(c) {
|
|
126
|
-
return <Text selectable={isSelectable}>{c}</Text>
|
|
127
|
-
})}
|
|
128
|
-
</View>
|
|
129
|
-
</View>
|
|
130
|
-
})}
|
|
131
|
-
</View>
|
|
132
|
-
}
|
|
133
83
|
"#
|
|
134
|
-
);
|
|
84
|
+
);
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
mod entry;
|
|
2
|
-
mod attributes;
|
|
3
|
-
mod shake;
|
|
4
|
-
mod condition;
|
|
5
|
-
mod looping;
|
|
6
|
-
|
|
7
1
|
use swc_core::ecma::{
|
|
8
2
|
parser,
|
|
9
|
-
visit::{as_folder, Fold
|
|
3
|
+
visit::{as_folder, Fold},
|
|
10
4
|
};
|
|
11
5
|
use crate::{
|
|
12
6
|
PluginConfig,
|
|
13
7
|
transform::*,
|
|
14
8
|
};
|
|
15
9
|
|
|
16
|
-
|
|
10
|
+
mod entry;
|
|
11
|
+
mod attributes;
|
|
12
|
+
mod shake;
|
|
13
|
+
mod condition;
|
|
14
|
+
mod looping;
|
|
15
|
+
mod children;
|
|
16
|
+
mod harmony;
|
|
17
|
+
|
|
18
|
+
pub fn tr () -> impl Fold {
|
|
17
19
|
let config = serde_json::from_str::<PluginConfig>(
|
|
18
20
|
r#"
|
|
19
21
|
{
|
|
@@ -95,4 +97,4 @@ pub fn get_syntax_config () -> parser::Syntax {
|
|
|
95
97
|
jsx: true,
|
|
96
98
|
..Default::default()
|
|
97
99
|
})
|
|
98
|
-
}
|
|
100
|
+
}
|
|
@@ -23,19 +23,5 @@ test!(
|
|
|
23
23
|
</View>
|
|
24
24
|
)
|
|
25
25
|
}
|
|
26
|
-
"#,
|
|
27
|
-
r#"
|
|
28
|
-
const TARO_TEMPLATES_f0t0 = '<template name="tmpl_0_f0t0"><view><text>Hello World!</text><text>Hello{{i.cn[0].cn[0].v}}World{{i.cn[0].cn[1].v}}!</text><view><text></text></view><view hover-stop-propagation="true" style="color: red"><text>Hello World!</text></view><view style="{{i.cn[1].st}}"><text>Hello World!</text></view></view></template>';
|
|
29
|
-
function Index () {
|
|
30
|
-
return <View compileMode="f0t0">
|
|
31
|
-
|
|
32
|
-
<Text>{T1}{T2}</Text>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<View style={myStyle}>
|
|
36
|
-
|
|
37
|
-
</View>
|
|
38
|
-
</View>
|
|
39
|
-
}
|
|
40
26
|
"#
|
|
41
|
-
);
|
|
27
|
+
);
|
|
@@ -3,124 +3,131 @@ use swc_core::{
|
|
|
3
3
|
common::{
|
|
4
4
|
iter::IdentifyLast,
|
|
5
5
|
util::take::Take,
|
|
6
|
-
DUMMY_SP as span
|
|
6
|
+
DUMMY_SP as span,
|
|
7
7
|
},
|
|
8
8
|
ecma::{
|
|
9
9
|
self,
|
|
10
10
|
ast::*,
|
|
11
|
-
atoms::Atom,
|
|
12
11
|
visit::{VisitMut, VisitMutWith},
|
|
12
|
+
utils::{quote_ident, quote_str},
|
|
13
13
|
},
|
|
14
|
+
atoms::Atom,
|
|
14
15
|
};
|
|
15
16
|
use std::collections::HashMap;
|
|
16
|
-
use std::rc::Rc;
|
|
17
17
|
use crate::PluginConfig;
|
|
18
18
|
use crate::utils::{self, constants::*};
|
|
19
19
|
|
|
20
20
|
struct PreVisitor {
|
|
21
|
-
is_in_jsx_expr_container: Rc<bool>,
|
|
22
21
|
is_in_and_expr: bool,
|
|
23
22
|
}
|
|
24
23
|
impl PreVisitor {
|
|
25
24
|
fn new () -> Self {
|
|
26
25
|
Self {
|
|
27
|
-
is_in_jsx_expr_container: Rc::new(true),
|
|
28
26
|
is_in_and_expr: false
|
|
29
27
|
}
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
30
|
impl VisitMut for PreVisitor {
|
|
33
|
-
fn
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Expr::Cond(CondExpr {
|
|
52
|
-
span,
|
|
53
|
-
test: condition.take(),
|
|
54
|
-
cons: right.take(),
|
|
55
|
-
alt: Box::new(utils::create_self_closing_jsx_element_expr(
|
|
56
|
-
element_name, // element 替换为同类型的元素。在显示/隐藏切换时,让运行时 diff 只更新必要属性而不是整个节点刷新
|
|
57
|
-
Some(vec![utils::create_jsx_bool_attr(COMPILE_IGNORE)]
|
|
58
|
-
)))
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
match &mut **right {
|
|
62
|
-
Expr::JSXElement(el) => {
|
|
63
|
-
let element_name = el.opening.name.clone();
|
|
64
|
-
inject_compile_if(el, left);
|
|
65
|
-
*expr = get_element_double(element_name, left, right);
|
|
66
|
-
},
|
|
67
|
-
Expr::Paren(ParenExpr { expr: paren_expr, .. }) => {
|
|
68
|
-
if paren_expr.is_jsx_element() {
|
|
69
|
-
let el: &mut Box<JSXElement> = paren_expr.as_mut_jsx_element().unwrap();
|
|
70
|
-
let element_name = el.opening.name.clone();
|
|
71
|
-
inject_compile_if(el, left);
|
|
72
|
-
*expr = get_element_double(element_name, left, paren_expr);
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
Expr::Lit(_) => {
|
|
76
|
-
*expr = Expr::Cond(CondExpr {
|
|
31
|
+
fn visit_mut_jsx_element_child (&mut self, child: &mut JSXElementChild) {
|
|
32
|
+
if let JSXElementChild::JSXExprContainer(JSXExprContainer { expr: JSXExpr::Expr(expr), .. }) = child {
|
|
33
|
+
let mut is_first_and_expr = false;
|
|
34
|
+
|
|
35
|
+
if let Expr::Paren(ParenExpr { expr: e, .. }) = &mut **expr {
|
|
36
|
+
*expr = e.take();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
match &mut **expr {
|
|
40
|
+
Expr::Bin(BinExpr { op, left, right, ..}) => {
|
|
41
|
+
// C&&A 替换为 C?A:A',原因是为了无论显示还是隐藏都保留一个元素,从而不影响兄弟节点的变量路径
|
|
42
|
+
if *op == op!("&&") && !self.is_in_and_expr {
|
|
43
|
+
is_first_and_expr = true;
|
|
44
|
+
fn inject_compile_if (el: &mut Box<JSXElement>, condition: &mut Box<Expr>) -> () {
|
|
45
|
+
el.opening.attrs.push(utils::create_jsx_expr_attr(COMPILE_IF, condition.clone()));
|
|
46
|
+
}
|
|
47
|
+
fn get_element_double (element_name: JSXElementName, condition: &mut Box<Expr>, right: &mut Box<Expr>) -> Expr {
|
|
48
|
+
Expr::Cond(CondExpr {
|
|
77
49
|
span,
|
|
78
|
-
test:
|
|
50
|
+
test: condition.take(),
|
|
79
51
|
cons: right.take(),
|
|
80
|
-
alt: Box::new(
|
|
52
|
+
alt: Box::new(utils::create_self_closing_jsx_element_expr(
|
|
53
|
+
element_name, // element 替换为同类型的元素。在显示/隐藏切换时,让运行时 diff 只更新必要属性而不是整个节点刷新
|
|
54
|
+
Some(vec![utils::create_jsx_bool_attr(COMPILE_IGNORE)]
|
|
55
|
+
)))
|
|
81
56
|
})
|
|
82
|
-
},
|
|
83
|
-
_ => {
|
|
84
|
-
// TODO Unknown fallback to template
|
|
85
|
-
println!("unknown expr: {right:?}");
|
|
86
57
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
58
|
+
match &mut **right {
|
|
59
|
+
Expr::JSXElement(el) => {
|
|
60
|
+
let element_name = el.opening.name.clone();
|
|
61
|
+
inject_compile_if(el, left);
|
|
62
|
+
**expr = get_element_double(element_name, left, right);
|
|
63
|
+
},
|
|
64
|
+
Expr::Paren(ParenExpr { expr: paren_expr, .. }) => {
|
|
65
|
+
if paren_expr.is_jsx_element() {
|
|
66
|
+
let el: &mut Box<JSXElement> = paren_expr.as_mut_jsx_element().unwrap();
|
|
67
|
+
let element_name = el.opening.name.clone();
|
|
68
|
+
inject_compile_if(el, left);
|
|
69
|
+
**expr = get_element_double(element_name, left, paren_expr);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
Expr::Lit(_) => {
|
|
73
|
+
**expr = Expr::Cond(CondExpr {
|
|
74
|
+
span,
|
|
75
|
+
test: left.take(),
|
|
76
|
+
cons: right.take(),
|
|
77
|
+
alt: Box::new(Expr::Lit(Lit::Str(quote_str!(COMPILE_IGNORE))))
|
|
78
|
+
})
|
|
79
|
+
},
|
|
80
|
+
_ => {
|
|
81
|
+
let jsx_el_name = JSXElementName::Ident(quote_ident!("block"));
|
|
82
|
+
let mut block = Box::new(JSXElement {
|
|
83
|
+
span,
|
|
84
|
+
opening: JSXOpeningElement { name: jsx_el_name.clone(), span, attrs: vec![], self_closing: false, type_args: None },
|
|
85
|
+
children: vec![JSXElementChild::JSXExprContainer(JSXExprContainer { span, expr: JSXExpr::Expr(right.take()) })],
|
|
86
|
+
closing: Some(JSXClosingElement { span, name: jsx_el_name.clone() })
|
|
87
|
+
});
|
|
88
|
+
inject_compile_if(&mut block, left);
|
|
89
|
+
**expr = get_element_double(jsx_el_name, left, &mut Box::new(Expr::JSXElement(block)));
|
|
90
|
+
}
|
|
107
91
|
}
|
|
108
92
|
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
93
|
+
},
|
|
94
|
+
Expr::Cond(CondExpr { test, cons, alt, ..}) => {
|
|
95
|
+
let compile_if = utils::create_jsx_expr_attr(COMPILE_IF, test.clone());
|
|
96
|
+
let compile_else = utils::create_jsx_bool_attr(COMPILE_ELSE);
|
|
97
|
+
let process_cond_arm = |arm: &mut Box<Expr>, attr: JSXAttrOrSpread| {
|
|
98
|
+
match &mut **arm {
|
|
99
|
+
Expr::JSXElement(el) => {
|
|
100
|
+
el.opening.attrs.push(attr);
|
|
101
|
+
},
|
|
102
|
+
_ => {
|
|
103
|
+
let temp = arm.take();
|
|
104
|
+
let jsx_el_name = JSXElementName::Ident(quote_ident!("block"));
|
|
105
|
+
**arm = Expr::JSXElement(Box::new(JSXElement {
|
|
106
|
+
span,
|
|
107
|
+
opening: JSXOpeningElement { name: jsx_el_name.clone(), span, attrs: vec![attr], self_closing: false, type_args: None },
|
|
108
|
+
children: vec![JSXElementChild::JSXExprContainer(JSXExprContainer { span, expr: JSXExpr::Expr(temp)})],
|
|
109
|
+
closing: Some(JSXClosingElement { span, name: jsx_el_name })
|
|
110
|
+
}))
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
process_cond_arm(cons, compile_if);
|
|
115
|
+
process_cond_arm(alt, compile_else);
|
|
116
|
+
},
|
|
117
|
+
_ => (),
|
|
118
|
+
}
|
|
115
119
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
if is_first_and_expr {
|
|
121
|
+
self.is_in_and_expr = true;
|
|
122
|
+
}
|
|
119
123
|
|
|
120
|
-
|
|
124
|
+
expr.visit_mut_children_with(self);
|
|
121
125
|
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
if is_first_and_expr {
|
|
127
|
+
self.is_in_and_expr = false;
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
child.visit_mut_children_with(self);
|
|
124
131
|
}
|
|
125
132
|
}
|
|
126
133
|
}
|
|
@@ -151,13 +158,13 @@ impl TransformVisitor {
|
|
|
151
158
|
let opening_element = &mut el.opening;
|
|
152
159
|
match &opening_element.name {
|
|
153
160
|
JSXElementName::Ident(ident) => {
|
|
154
|
-
let name = utils::to_kebab_case(
|
|
161
|
+
let name = utils::to_kebab_case(ident.as_ref());
|
|
155
162
|
match self.config.components.get(&name) {
|
|
156
163
|
// 内置组件
|
|
157
164
|
Some(attrs_map) => {
|
|
158
165
|
let attrs = self.build_xml_attrs(opening_element, attrs_map);
|
|
159
166
|
if attrs.is_none() { return String::new() };
|
|
160
|
-
let children = self.build_xml_children(el);
|
|
167
|
+
let (children, ..) = self.build_xml_children(&mut el.children, None);
|
|
161
168
|
format!("<{}{}>{}</{}>", name, attrs.unwrap(), children, name)
|
|
162
169
|
},
|
|
163
170
|
None => {
|
|
@@ -180,8 +187,8 @@ impl TransformVisitor {
|
|
|
180
187
|
if let JSXAttrOrSpread::JSXAttr(jsx_attr) = attr {
|
|
181
188
|
if let JSXAttrName::Ident(Ident { sym: name, .. }) = &jsx_attr.name {
|
|
182
189
|
let jsx_attr_name = name.to_string();
|
|
183
|
-
|
|
184
|
-
if jsx_attr_name
|
|
190
|
+
|
|
191
|
+
if REACT_RESERVED.contains(&jsx_attr_name.as_str()) {
|
|
185
192
|
return true;
|
|
186
193
|
}
|
|
187
194
|
|
|
@@ -269,25 +276,24 @@ impl TransformVisitor {
|
|
|
269
276
|
Some(attrs_string)
|
|
270
277
|
}
|
|
271
278
|
|
|
272
|
-
fn build_xml_children (&mut self,
|
|
279
|
+
fn build_xml_children (&mut self, children: &mut Vec<JSXElementChild>, retain_start_from: Option<i32>) -> (String, i32) {
|
|
273
280
|
let mut children_string = String::new();
|
|
274
|
-
let
|
|
281
|
+
let start = if retain_start_from.is_some() { retain_start_from.unwrap() } else { 0 };
|
|
282
|
+
let mut retain_child_counter = start;
|
|
275
283
|
|
|
276
|
-
|
|
277
|
-
.
|
|
278
|
-
|
|
284
|
+
children
|
|
285
|
+
.retain_mut(|child| {
|
|
286
|
+
let mut is_retain = true;
|
|
279
287
|
self.node_stack.push(retain_child_counter);
|
|
280
288
|
match child {
|
|
281
289
|
JSXElementChild::JSXElement(child_el) => {
|
|
282
290
|
let child_string = self.build_xml_element(&mut **child_el);
|
|
283
291
|
children_string.push_str(&child_string);
|
|
284
292
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
let raw: Atom = "To be removed".into();
|
|
288
|
-
*child = JSXElementChild::JSXText(JSXText { span, value: raw.clone(), raw });
|
|
293
|
+
if utils::is_static_jsx(child_el) && utils::is_inner_component(child_el, &self.config) {
|
|
294
|
+
is_retain = false
|
|
289
295
|
} else {
|
|
290
|
-
retain_child_counter
|
|
296
|
+
retain_child_counter += 1;
|
|
291
297
|
}
|
|
292
298
|
},
|
|
293
299
|
JSXElementChild::JSXExprContainer(JSXExprContainer {
|
|
@@ -297,6 +303,7 @@ impl TransformVisitor {
|
|
|
297
303
|
if let Expr::Paren(ParenExpr { expr, .. }) = &mut **jsx_expr {
|
|
298
304
|
*jsx_expr = expr.take();
|
|
299
305
|
}
|
|
306
|
+
let node_path = self.get_current_node_path();
|
|
300
307
|
match &mut **jsx_expr {
|
|
301
308
|
Expr::Cond(CondExpr { cons, alt, ..}) => {
|
|
302
309
|
let mut process_condition_expr = |arm: &mut Box<Expr>| {
|
|
@@ -307,12 +314,14 @@ impl TransformVisitor {
|
|
|
307
314
|
},
|
|
308
315
|
Expr::Lit(lit) => {
|
|
309
316
|
if let Lit::Str(Str { value, .. }) = lit {
|
|
310
|
-
if
|
|
317
|
+
if value == COMPILE_IGNORE {
|
|
311
318
|
return ();
|
|
312
319
|
}
|
|
313
320
|
}
|
|
314
|
-
|
|
315
|
-
|
|
321
|
+
// {condition1 && 'Hello'} 在预处理时会变成 {condition1 ? 'Hello' : "compileIgnore"}
|
|
322
|
+
// 而普通文本三元则会被 block 标签包裹,因此处理后只有上述情况会存在 lit 类型的表达式
|
|
323
|
+
// 由于这种情况没有办法使用 wx:if 来处理,需要特殊处理成 {{i.cn[3].v==="compileIgnore"?"":i.cn[3].v}} 的形式
|
|
324
|
+
let str = format!(r#"{{{{{}.v==="{}"?"":{}.v}}}}"#, node_path, COMPILE_IGNORE, node_path);
|
|
316
325
|
children_string.push_str(&str);
|
|
317
326
|
},
|
|
318
327
|
_ => ()
|
|
@@ -332,41 +341,48 @@ impl TransformVisitor {
|
|
|
332
341
|
self.node_stack.push(LOOP_WRAPPER_ID);
|
|
333
342
|
let child_string = self.build_xml_element(&mut *return_value);
|
|
334
343
|
children_string.push_str(&child_string);
|
|
344
|
+
} else if utils::is_render_fn(callee_expr) {
|
|
345
|
+
let tmpl = format!(r#"<template is="{{{{xs.a(c, {}.nn, l)}}}}" data="{{{{i:{},c:c+1,l:xs.f(l,{}.nn)}}}}" />"#, node_path, node_path, node_path);
|
|
346
|
+
children_string.push_str(&tmpl)
|
|
347
|
+
} else {
|
|
348
|
+
let code = utils::gen_template_v(&node_path);
|
|
349
|
+
children_string.push_str(&code);
|
|
335
350
|
}
|
|
336
351
|
},
|
|
337
|
-
// TODO 只支持 render 开头的函数调用返回 JSX
|
|
338
|
-
// Expr::Call(_)
|
|
339
352
|
_ => {
|
|
340
|
-
|
|
341
|
-
let node_path = self.get_current_node_path();
|
|
342
|
-
let code = format!("{{{{{}.v}}}}", node_path);
|
|
353
|
+
let code = utils::gen_template_v(&node_path);
|
|
343
354
|
children_string.push_str(&code);
|
|
344
355
|
}
|
|
345
356
|
}
|
|
346
357
|
retain_child_counter = retain_child_counter + 1
|
|
347
358
|
},
|
|
348
|
-
JSXElementChild::JSXText(
|
|
349
|
-
let content = utils::jsx_text_to_string(
|
|
359
|
+
JSXElementChild::JSXText(JSXText { value, .. }) => {
|
|
360
|
+
let content = utils::jsx_text_to_string(value);
|
|
350
361
|
if !content.is_empty() {
|
|
351
362
|
children_string.push_str(&content);
|
|
363
|
+
// JSX 过滤掉静态文本节点,只在模板中保留。同时保留用于换行、空格的静态文本节点
|
|
364
|
+
is_retain = false
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
JSXElementChild::JSXFragment(child_el) => {
|
|
368
|
+
self.node_stack.pop();
|
|
369
|
+
let (child_string, inner_retain) = self.build_xml_children(&mut child_el.children, Some(retain_child_counter));
|
|
370
|
+
children_string.push_str(&child_string);
|
|
371
|
+
if inner_retain == 0 {
|
|
372
|
+
// 静态 fragment,在 JSX 中删除
|
|
373
|
+
is_retain = false
|
|
374
|
+
} else {
|
|
375
|
+
retain_child_counter += inner_retain;
|
|
352
376
|
}
|
|
377
|
+
self.node_stack.push(retain_child_counter);
|
|
353
378
|
},
|
|
354
379
|
_ => ()
|
|
355
380
|
}
|
|
356
381
|
self.node_stack.pop();
|
|
382
|
+
return is_retain
|
|
357
383
|
});
|
|
358
384
|
|
|
359
|
-
|
|
360
|
-
// JSX 过滤掉静态文本节点,只在模板中保留
|
|
361
|
-
match item {
|
|
362
|
-
JSXElementChild::JSXText(jsx_text) => {
|
|
363
|
-
utils::is_empty_jsx_text_line(&jsx_text.value)
|
|
364
|
-
},
|
|
365
|
-
_ => true
|
|
366
|
-
}
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
children_string
|
|
385
|
+
(children_string, retain_child_counter - start)
|
|
370
386
|
}
|
|
371
387
|
|
|
372
388
|
fn get_current_node_path (&self) -> String {
|
|
@@ -411,14 +427,10 @@ impl VisitMut for TransformVisitor {
|
|
|
411
427
|
for attr in &mut el.opening.attrs {
|
|
412
428
|
if let JSXAttrOrSpread::JSXAttr(jsx_attr) = attr {
|
|
413
429
|
if let JSXAttrName::Ident(jsx_attr_name) = &jsx_attr.name {
|
|
414
|
-
if
|
|
430
|
+
if jsx_attr_name.sym == COMPILE_MODE {
|
|
415
431
|
self.is_compile_mode = true;
|
|
416
432
|
tmpl_name = (self.get_tmpl_name)();
|
|
417
|
-
jsx_attr.value = Some(JSXAttrValue::Lit(Lit::Str(
|
|
418
|
-
span,
|
|
419
|
-
value: tmpl_name.clone().into(),
|
|
420
|
-
raw: None,
|
|
421
|
-
})));
|
|
433
|
+
jsx_attr.value = Some(JSXAttrValue::Lit(Lit::Str(quote_str!(tmpl_name.as_str()))));
|
|
422
434
|
break;
|
|
423
435
|
}
|
|
424
436
|
}
|
|
@@ -451,12 +463,8 @@ impl VisitMut for TransformVisitor {
|
|
|
451
463
|
declare: false,
|
|
452
464
|
decls: vec![VarDeclarator {
|
|
453
465
|
span,
|
|
454
|
-
name: Pat::Ident(Ident::new(format!("TARO_TEMPLATES_{}", key)
|
|
455
|
-
init: Some(Box::new(Expr::Lit(Lit::Str(
|
|
456
|
-
span,
|
|
457
|
-
value: value.as_str().into(),
|
|
458
|
-
raw: None
|
|
459
|
-
})))),
|
|
466
|
+
name: Pat::Ident(Ident::new(Atom::new(format!("TARO_TEMPLATES_{}", key)), span).into()),
|
|
467
|
+
init: Some(Box::new(Expr::Lit(Lit::Str(quote_str!(value.as_str()))))),
|
|
460
468
|
definite: false,
|
|
461
469
|
}],
|
|
462
470
|
}))))
|