1
1
use next_binding:: swc:: core:: {
2
- common:: { errors:: HANDLER , util:: take:: Take , FileName , DUMMY_SP } ,
2
+ common:: {
3
+ comments:: { Comment , CommentKind , Comments } ,
4
+ errors:: HANDLER ,
5
+ util:: take:: Take ,
6
+ BytePos , FileName , DUMMY_SP ,
7
+ } ,
3
8
ecma:: {
4
9
ast:: {
5
10
op, ArrayLit , AssignExpr , BlockStmt , CallExpr , ComputedPropName , Decl , ExportDecl ,
6
11
Expr , ExprStmt , FnDecl , Function , Id , Ident , KeyValueProp , Lit , MemberExpr , MemberProp ,
7
- ModuleDecl , ModuleItem , PatOrExpr , Prop , PropName , ReturnStmt , Stmt , Str , VarDecl ,
8
- VarDeclKind , VarDeclarator ,
12
+ Module , ModuleDecl , ModuleItem , PatOrExpr , Prop , PropName , ReturnStmt , Stmt , Str ,
13
+ VarDecl , VarDeclKind , VarDeclarator ,
9
14
} ,
10
15
atoms:: JsWord ,
11
16
utils:: { find_pat_ids, private_ident, quote_ident, ExprFactory } ,
@@ -19,28 +24,40 @@ use serde::Deserialize;
19
24
20
25
#[ derive( Clone , Debug , Deserialize ) ]
21
26
#[ serde( deny_unknown_fields, rename_all = "camelCase" ) ]
22
- pub struct Config { }
27
+ pub struct Config {
28
+ pub is_server : bool ,
29
+ }
23
30
24
- pub fn server_actions ( file_name : & FileName , config : Config ) -> impl VisitMut + Fold {
31
+ pub fn server_actions < C : Comments > (
32
+ file_name : & FileName ,
33
+ config : Config ,
34
+ comments : C ,
35
+ ) -> impl VisitMut + Fold {
25
36
as_folder ( ServerActions {
26
37
config,
38
+ comments,
27
39
file_name : file_name. clone ( ) ,
40
+ start_pos : BytePos ( 0 ) ,
28
41
in_action_file : false ,
29
42
in_export_decl : false ,
43
+ has_action : false ,
30
44
top_level : false ,
31
45
closure_candidates : Default :: default ( ) ,
32
46
annotations : Default :: default ( ) ,
33
47
extra_items : Default :: default ( ) ,
34
48
} )
35
49
}
36
50
37
- struct ServerActions {
51
+ struct ServerActions < C : Comments > {
38
52
#[ allow( unused) ]
39
53
config : Config ,
40
54
file_name : FileName ,
55
+ comments : C ,
41
56
57
+ start_pos : BytePos ,
42
58
in_action_file : bool ,
43
59
in_export_decl : bool ,
60
+ has_action : bool ,
44
61
top_level : bool ,
45
62
46
63
closure_candidates : Vec < Id > ,
@@ -49,7 +66,7 @@ struct ServerActions {
49
66
extra_items : Vec < ModuleItem > ,
50
67
}
51
68
52
- impl VisitMut for ServerActions {
69
+ impl < C : Comments > VisitMut for ServerActions < C > {
53
70
fn visit_mut_export_decl ( & mut self , decl : & mut ExportDecl ) {
54
71
let old = self . in_export_decl ;
55
72
self . in_export_decl = true ;
@@ -97,6 +114,8 @@ impl VisitMut for ServerActions {
97
114
let action_name: JsWord = format ! ( "$ACTION_{}" , f. ident. sym) . into ( ) ;
98
115
let action_ident = private_ident ! ( action_name. clone( ) ) ;
99
116
117
+ self . has_action = true ;
118
+
100
119
// myAction.$$typeof = Symbol.for('react.action.reference');
101
120
self . annotations . push ( annotate (
102
121
& f. ident ,
@@ -124,22 +143,24 @@ impl VisitMut for ServerActions {
124
143
. push ( annotate ( & f. ident , "$$name" , action_name. into ( ) ) ) ;
125
144
126
145
if self . top_level {
127
- // export const $ACTION_myAction = myAction;
128
- self . extra_items
129
- . push ( ModuleItem :: ModuleDecl ( ModuleDecl :: ExportDecl ( ExportDecl {
130
- span : DUMMY_SP ,
131
- decl : Decl :: Var ( Box :: new ( VarDecl {
146
+ if !( self . in_action_file && self . in_export_decl ) {
147
+ // export const $ACTION_myAction = myAction;
148
+ self . extra_items
149
+ . push ( ModuleItem :: ModuleDecl ( ModuleDecl :: ExportDecl ( ExportDecl {
132
150
span : DUMMY_SP ,
133
- kind : VarDeclKind :: Const ,
134
- declare : Default :: default ( ) ,
135
- decls : vec ! [ VarDeclarator {
151
+ decl : Decl :: Var ( Box :: new ( VarDecl {
136
152
span : DUMMY_SP ,
137
- name: action_ident. into( ) ,
138
- init: Some ( f. ident. clone( ) . into( ) ) ,
139
- definite: Default :: default ( ) ,
140
- } ] ,
141
- } ) ) ,
142
- } ) ) ) ;
153
+ kind : VarDeclKind :: Const ,
154
+ declare : Default :: default ( ) ,
155
+ decls : vec ! [ VarDeclarator {
156
+ span: DUMMY_SP ,
157
+ name: action_ident. into( ) ,
158
+ init: Some ( f. ident. clone( ) . into( ) ) ,
159
+ definite: Default :: default ( ) ,
160
+ } ] ,
161
+ } ) ) ,
162
+ } ) ) ) ;
163
+ }
143
164
} else {
144
165
// Hoist the function to the top level.
145
166
@@ -215,25 +236,17 @@ impl VisitMut for ServerActions {
215
236
}
216
237
}
217
238
218
- fn visit_mut_module_item ( & mut self , s : & mut ModuleItem ) {
219
- s. visit_mut_children_with ( self ) ;
220
-
221
- if self . in_action_file {
222
- if let ModuleItem :: ModuleDecl ( ModuleDecl :: ExportDecl ( ExportDecl {
223
- decl : decl @ Decl :: Fn ( ..) ,
224
- ..
225
- } ) ) = s
226
- {
227
- * s = ModuleItem :: Stmt ( Stmt :: Decl ( decl. take ( ) ) ) ;
228
- }
229
- }
239
+ fn visit_mut_module ( & mut self , m : & mut Module ) {
240
+ self . start_pos = m. span . lo ;
241
+ m. visit_mut_children_with ( self ) ;
230
242
}
231
243
232
244
fn visit_mut_module_items ( & mut self , stmts : & mut Vec < ModuleItem > ) {
233
245
if let Some ( ModuleItem :: Stmt ( Stmt :: Expr ( first) ) ) = stmts. first ( ) {
234
246
match & * first. expr {
235
247
Expr :: Lit ( Lit :: Str ( Str { value, .. } ) ) if value == "use action" => {
236
248
self . in_action_file = true ;
249
+ self . has_action = true ;
237
250
}
238
251
_ => { }
239
252
}
@@ -258,6 +271,18 @@ impl VisitMut for ServerActions {
258
271
* stmts = new;
259
272
260
273
self . annotations = old_annotations;
274
+
275
+ if self . has_action {
276
+ // Prepend a special comment to the top of the file.
277
+ self . comments . add_leading (
278
+ self . start_pos ,
279
+ Comment {
280
+ span : DUMMY_SP ,
281
+ kind : CommentKind :: Block ,
282
+ text : " __next_internal_action_entry_do_not_use__ " . into ( ) ,
283
+ } ,
284
+ ) ;
285
+ }
261
286
}
262
287
263
288
fn visit_mut_stmts ( & mut self , stmts : & mut Vec < Stmt > ) {
0 commit comments