@@ -29,22 +29,28 @@ const getVisitor = ({ $program, usedCompilers }) => ({
2929 // 0. process only templates which are in usedCompilers (imported from our library)
3030 if ( ! shouldProcess ( $this , usedCompilers ) ) return
3131
32- // I. validate template
33- validateTemplate ( $this )
34-
3532 const compiler = usedCompilers . get ( $this . node . tag . name )
33+ const { source, expressions } = lowerTemplate ( $this . node . quasi )
34+ const hasExpressions = expressions . length > 0
35+
36+ // I. find parent function or program
37+ const $function = $this . getFunctionParent ( )
38+ if ( hasExpressions && ! $function ) {
39+ throw $this . buildCodeFrameError ( `
40+ [@cssxjs/babel-plugin-rn-stylename-inline] Expression interpolations are supported only inside function-scoped css\`\` and styl\`\` templates.
41+ ` )
42+ }
3643
3744 // II. compile template
38- const source = $this . node . quasi . quasis [ 0 ] ?. value ?. raw || ''
3945 const filename = state . file ?. opts ?. filename
4046 const platform = state . opts ?. platform || state . file ?. opts ?. caller ?. platform || DEFAULT_PLATFORM
41- const compiledString = compiler ( source , filename , { platform } )
47+ const compiledString = compiler ( source , filename , {
48+ platform,
49+ template : hasExpressions
50+ } )
4251 const compiledExpression = parser . parseExpression ( compiledString )
4352
44- // III. find parent function or program
45- const $function = $this . getFunctionParent ( )
46-
47- // IV. LOCAL. if parent is function -- handle local
53+ // III. LOCAL. if parent is function -- handle local
4854 if ( $function ) {
4955 // 1. define a `const` variable at the top of the file
5056 // with the unique identifier
@@ -54,14 +60,21 @@ const getVisitor = ({ $program, usedCompilers }) => ({
5460 value : compiledExpression
5561 } ) )
5662
57- // 2. reassign this unique identifier to a constant LOCAL_NAME
63+ const localValue = hasExpressions
64+ ? t . objectExpression ( [
65+ t . objectProperty ( t . identifier ( 'sheet' ) , localIdentifier ) ,
66+ t . objectProperty ( t . identifier ( 'values' ) , t . arrayExpression ( expressions ) )
67+ ] )
68+ : localIdentifier
69+
70+ // 2. reassign this unique identifier or local dynamic layer to a constant LOCAL_NAME
5871 // in the scope of current function
5972 $function . get ( 'body' ) . unshiftContainer ( 'body' , buildConst ( {
6073 variable : t . identifier ( LOCAL_NAME ) ,
61- value : localIdentifier
74+ value : localValue
6275 } ) )
6376
64- // V . GLOBAL. if parent is program -- handle global
77+ // IV . GLOBAL. if parent is program -- handle global
6578 } else {
6679 // 1. define a `const` variable at the top of the file
6780 // with the constant GLOBAL_NAME
@@ -71,7 +84,7 @@ const getVisitor = ({ $program, usedCompilers }) => ({
7184 } ) )
7285 }
7386
74- // VI . Remove template expression after processing
87+ // V . Remove template expression after processing
7588 $this . remove ( )
7689
7790 // TODO: Throw error if global styles were already added or
@@ -98,14 +111,19 @@ function shouldProcess ($template, usedCompilers) {
98111 return true
99112}
100113
101- function validateTemplate ( $template ) {
102- const { node : { quasi } } = $template
114+ function lowerTemplate ( quasi ) {
115+ let source = ''
116+ const expressions = [ ]
103117
104- if ( quasi . expressions . length > 0 ) {
105- throw $template . buildCodeFrameError ( `
106- [@cssxjs/babel-plugin-rn-stylename-inline] Expression interpolations are not supported in css\`\` and styl\`\`.
107- ` )
118+ for ( let index = 0 ; index < quasi . quasis . length ; index ++ ) {
119+ source += quasi . quasis [ index ] ?. value ?. raw || ''
120+ const expression = quasi . expressions [ index ]
121+ if ( ! expression ) continue
122+ source += `var(--__cssx_dynamic_${ expressions . length } )`
123+ expressions . push ( expression )
108124 }
125+
126+ return { source, expressions }
109127}
110128
111129function getUsedCompilers ( $program , state ) {
0 commit comments