@@ -4,16 +4,19 @@ use std::iter::once;
44
55use swc_atoms:: { atom, Atom } ;
66use swc_common:: {
7- comments:: Comments , errors:: HANDLER , sync:: Lrc , util:: take:: Take , BytePos , Mark , Spanned ,
8- SyntaxContext , DUMMY_SP ,
7+ comments:: Comments , errors:: HANDLER , sync:: Lrc , util:: take:: Take , BytePos , Mark , SourceMap ,
8+ Spanned , SyntaxContext , DUMMY_SP ,
99} ;
1010use swc_ecma_ast:: * ;
1111use swc_ecma_utils:: { prepend_stmt, private_ident, quote_ident, ExprFactory , StmtLike } ;
1212use swc_ecma_visit:: { noop_visit_mut_type, visit_mut_pass, VisitMut , VisitMutWith } ;
1313
1414use crate :: {
15- jsx:: should_use_create_element, jsx_name, jsx_text_to_str, transform_jsx_attr_str,
16- AutomaticConfig , CommonConfig ,
15+ jsx:: {
16+ development:: { visit_mut_development, DevelopmentContext , JsxDev } ,
17+ should_use_create_element,
18+ } ,
19+ jsx_name, jsx_text_to_str, transform_jsx_attr_str, AutomaticConfig , CommonConfig ,
1720} ;
1821
1922/// Automatic runtime JSX transformer
@@ -27,6 +30,7 @@ pub fn automatic<C>(
2730 common : CommonConfig ,
2831 unresolved_mark : Mark ,
2932 comments : Option < C > ,
33+ cm : Lrc < SourceMap > ,
3034) -> impl Pass + VisitMut
3135where
3236 C : Comments + ' static ,
4650 import_fragment : None ,
4751 import_create_element : None ,
4852
49- development : common. development . into_bool ( ) ,
5053 throw_if_namespace : common. throw_if_namespace . into_bool ( ) ,
54+
55+ development : common. development . into_bool ( ) ,
56+ development_ctx : DevelopmentContext :: default ( ) ,
57+
5158 add_pure_comment,
59+ cm,
5260 } )
5361}
5462
@@ -61,10 +69,13 @@ struct Automatic {
6169 import_create_element : Option < Ident > ,
6270 import_fragment : Option < Ident > ,
6371
64- development : bool ,
6572 throw_if_namespace : bool ,
6673
74+ development : bool ,
75+ development_ctx : DevelopmentContext ,
76+
6777 add_pure_comment : Lrc < dyn Fn ( BytePos ) > ,
78+ cm : Lrc < SourceMap > ,
6879}
6980
7081impl Automatic {
@@ -241,8 +252,6 @@ impl Automatic {
241252 } ;
242253
243254 let mut key = None ;
244- let mut source_props = None ;
245- let mut self_props = None ;
246255
247256 for attr in el. opening . attrs {
248257 match attr {
@@ -270,36 +279,6 @@ impl Automatic {
270279 continue ;
271280 }
272281
273- if !use_create_element && * i. sym == * "__source" && self . development {
274- if source_props. is_some ( ) {
275- panic ! ( "Duplicate __source is found" ) ;
276- }
277- source_props = attr
278- . value
279- . and_then ( jsx_attr_value_to_expr)
280- . map ( |expr| expr. as_arg ( ) ) ;
281- assert_ne ! (
282- source_props, None ,
283- "value of property '__source' should not be empty"
284- ) ;
285- continue ;
286- }
287-
288- if !use_create_element && * i. sym == * "__self" && self . development {
289- if self_props. is_some ( ) {
290- panic ! ( "Duplicate __self is found" ) ;
291- }
292- self_props = attr
293- . value
294- . and_then ( jsx_attr_value_to_expr)
295- . map ( |expr| expr. as_arg ( ) ) ;
296- assert_ne ! (
297- self_props, None ,
298- "value of property '__self' should not be empty"
299- ) ;
300- continue ;
301- }
302-
303282 let value = match attr. value {
304283 Some ( v) => {
305284 jsx_attr_value_to_expr ( v) . expect ( "empty expression container?" )
@@ -407,6 +386,23 @@ impl Automatic {
407386 }
408387 }
409388
389+ if use_create_element && self . development {
390+ props_obj. props . push (
391+ Prop :: KeyValue ( KeyValueProp {
392+ key : quote_ident ! ( "__source" ) . into ( ) ,
393+ value : self . source_props ( el. span . lo ) . into ( ) ,
394+ } )
395+ . into ( ) ,
396+ ) ;
397+ props_obj. props . push (
398+ Prop :: KeyValue ( KeyValueProp {
399+ key : quote_ident ! ( "__self" ) . into ( ) ,
400+ value : self . self_props ( ) . into ( ) ,
401+ } )
402+ . into ( ) ,
403+ ) ;
404+ }
405+
410406 let args = once ( name. as_arg ( ) ) . chain ( once ( props_obj. as_arg ( ) ) ) ;
411407 let args = if use_create_element {
412408 args. chain ( children. into_iter ( ) . flatten ( ) ) . collect ( )
@@ -417,21 +413,10 @@ impl Automatic {
417413 None => Expr :: undefined ( DUMMY_SP ) . as_arg ( ) ,
418414 } ;
419415
420- // set undefined literal to __source if __source is None
421- let source_props = match source_props {
422- Some ( source_props) => source_props,
423- None => Expr :: undefined ( DUMMY_SP ) . as_arg ( ) ,
424- } ;
425-
426- // set undefined literal to __self if __self is None
427- let self_props = match self_props {
428- Some ( self_props) => self_props,
429- None => Expr :: undefined ( DUMMY_SP ) . as_arg ( ) ,
430- } ;
431416 args. chain ( once ( key) )
432417 . chain ( once ( use_jsxs. as_arg ( ) ) )
433- . chain ( once ( source_props) )
434- . chain ( once ( self_props) )
418+ . chain ( once ( self . source_props ( el . span . lo ) . as_arg ( ) ) )
419+ . chain ( once ( self . self_props ( ) . as_arg ( ) ) )
435420 . collect ( )
436421 } else {
437422 args. chain ( key) . collect ( )
@@ -488,9 +473,44 @@ impl Automatic {
488473 }
489474}
490475
476+ impl Automatic {
477+ fn source_props ( & self , pos : BytePos ) -> ObjectLit {
478+ let loc = self . cm . lookup_char_pos ( pos) ;
479+
480+ ObjectLit {
481+ props : vec ! [
482+ Prop :: KeyValue ( KeyValueProp {
483+ key: quote_ident!( "fileName" ) . into( ) ,
484+ value: loc. file. name. to_string( ) . into( ) ,
485+ } )
486+ . into( ) ,
487+ Prop :: KeyValue ( KeyValueProp {
488+ key: quote_ident!( "lineNumber" ) . into( ) ,
489+ value: loc. line. into( ) ,
490+ } )
491+ . into( ) ,
492+ Prop :: KeyValue ( KeyValueProp {
493+ key: quote_ident!( "columnNumber" ) . into( ) ,
494+ value: ( loc. col. 0 + 1 ) . into( ) ,
495+ } )
496+ . into( ) ,
497+ ] ,
498+ ..Default :: default ( )
499+ }
500+ }
501+ }
502+
503+ impl JsxDev for Automatic {
504+ fn development_ctxt ( & mut self ) -> & mut DevelopmentContext {
505+ & mut self . development_ctx
506+ }
507+ }
508+
491509impl VisitMut for Automatic {
492510 noop_visit_mut_type ! ( ) ;
493511
512+ visit_mut_development ! ( ) ;
513+
494514 fn visit_mut_expr ( & mut self , expr : & mut Expr ) {
495515 if let Expr :: JSXElement ( el) = expr {
496516 // <div></div> => React.createElement('div', null);
0 commit comments