@@ -25,6 +25,7 @@ import {
25
25
import {
26
26
camelize ,
27
27
capitalize ,
28
+ getClassNameForTagName ,
28
29
invariant ,
29
30
last ,
30
31
pascalCase ,
@@ -117,22 +118,6 @@ export function generate(
117
118
) : TransformedCode {
118
119
ctx = createGenerateContext ( options )
119
120
120
- if ( ctx . used . components . size > 0 ) {
121
- wrap (
122
- `${ annotations . templateGlobals . start } \n` ,
123
- `${ annotations . templateGlobals . end } \n` ,
124
- ( ) => {
125
- ctx . used . components . forEach ( ( component ) => {
126
- if ( isSimpleIdentifier ( component ) ) {
127
- writeLine (
128
- `const ${ ctx . internalIdentifierPrefix } _get_identifier_${ component } = () => ${ component } ;` ,
129
- )
130
- }
131
- } )
132
- } ,
133
- )
134
- }
135
-
136
121
genRootNode ( root )
137
122
genSlotTypes ( root )
138
123
genAttrTypes ( root )
@@ -206,14 +191,25 @@ function genRootNode(node: RootNode): void {
206
191
}
207
192
208
193
function genKnownIdentifierGetters ( ids : string [ ] ) : void {
209
- const known = ids . filter ( ( id ) => ctx . identifiers . has ( id ) )
210
- if ( known . length === 0 ) return
194
+ ids = Array . from (
195
+ new Set ( [ ...ids , ...ctx . used . components , ...ctx . used . directives ] ) ,
196
+ )
197
+ if ( ! ids . some ( ( id ) => ctx . identifiers . has ( id ) ) ) return
211
198
wrap (
212
199
annotations . templateGlobals . start ,
213
200
annotations . templateGlobals . end ,
214
201
( ) => {
215
202
ctx . newLine ( )
216
- known . forEach ( ( id ) => {
203
+ ids . forEach ( ( id ) => {
204
+ const knownId = ctx . identifiers . get ( id )
205
+ if ( knownId == null ) return
206
+ if (
207
+ ! [ 'ref' , 'maybeRef' , 'externalMaybeRef' , 'externalRef' ] . includes (
208
+ knownId . kind ,
209
+ )
210
+ )
211
+ return
212
+
217
213
writeLine (
218
214
`const ${
219
215
ctx . internalIdentifierPrefix
@@ -287,10 +283,17 @@ function genGlobalDeclarations(node: Node): void {
287
283
if ( node . scope . globals . length === 0 ) return
288
284
writeLine ( annotations . templateGlobals . start )
289
285
node . scope . globals . forEach ( ( id ) => {
290
- if ( ctx . identifiers . has ( id ) ) {
291
- writeLine (
292
- `let ${ id } = ${ ctx . internalIdentifierPrefix } _get_identifier_${ id } ();` ,
293
- )
286
+ const knownId = ctx . identifiers . get ( id )
287
+ if ( knownId != null ) {
288
+ if (
289
+ [ 'ref' , 'maybeRef' , 'externalMaybeRef' , 'externalRef' ] . includes (
290
+ knownId . kind ,
291
+ )
292
+ ) {
293
+ writeLine (
294
+ `let ${ id } = ${ ctx . internalIdentifierPrefix } _get_identifier_${ id } ();` ,
295
+ )
296
+ }
294
297
} else {
295
298
writeLine ( `let ${ id } = ${ ctx . contextIdentifier } .${ id } ` )
296
299
}
@@ -317,9 +320,12 @@ function genElementNode(node: ElementNode): void {
317
320
ctx . write ( `${ annotations . tsxCompletions } ` )
318
321
} )
319
322
ctx . newLine ( )
323
+ } else {
324
+ return // tag is empty, when only "<" is present
320
325
}
326
+
321
327
if ( node . isSelfClosing ) {
322
- ctx . write ( '/>' )
328
+ ctx . write ( '/>' , node . endTagLoc )
323
329
return // done
324
330
}
325
331
ctx . write ( '>' ) . newLine ( )
@@ -390,15 +396,15 @@ function genComponentNode(node: ComponentNode): void {
390
396
391
397
genDirectiveChecks ( node )
392
398
ctx . write ( '<' , node . loc )
393
- ctx . write ( node . resolvedName ?? node . tag , node . tagLoc ) . newLine ( )
399
+ ctx . write ( node . resolvedName ?? node . tag , node . tagLoc , true ) . newLine ( )
394
400
indent ( ( ) => {
395
401
genProps ( node )
396
402
ctx . write ( `${ annotations . tsxCompletions } ` )
397
403
} )
398
404
399
405
ctx . newLine ( )
400
406
if ( node . isSelfClosing ) {
401
- writeLine ( '/>' )
407
+ ctx . write ( '/>' , node . endTagLoc ) . newLine ( )
402
408
return // done
403
409
}
404
410
writeLine ( '>' )
@@ -563,16 +569,13 @@ function genProps(el: ElementNode | ComponentNode): void {
563
569
ctx . newLine ( )
564
570
} else if ( prop . name === 'on' ) {
565
571
if ( prop . arg == null ) {
566
- ctx . write ( '{...(' )
567
- if ( prop . exp != null ) {
568
- genExpressionNode ( prop . exp )
572
+ if ( prop . exp == null ) {
573
+ ctx . write ( 'on' , prop . loc , true )
569
574
} else {
570
- ctx . write (
571
- annotations . missingExpression ,
572
- createLoc ( prop . loc , prop . loc . source . length ) ,
573
- )
575
+ ctx . write ( '{...(' )
576
+ genExpressionNode ( prop . exp )
577
+ ctx . write ( ')}' )
574
578
}
575
- ctx . write ( ')}' )
576
579
} else {
577
580
invariant ( isSimpleExpressionNode ( prop . arg ) )
578
581
const id = prop . arg . content
@@ -584,6 +587,15 @@ function genProps(el: ElementNode | ComponentNode): void {
584
587
)
585
588
586
589
const genHandler = ( ) : void => {
590
+ if ( isPlainElementNode ( el ) ) {
591
+ ctx . typeGuards . push (
592
+ createCompoundExpression ( [
593
+ `$event.currentTarget instanceof ` ,
594
+ getClassNameForTagName ( el . tag ) ,
595
+ ] ) ,
596
+ )
597
+ }
598
+
587
599
ctx . write ( `${ getRuntimeFn ( ctx . typeIdentifier , 'first' ) } ([` ) . newLine ( )
588
600
indent ( ( ) => {
589
601
all . forEach ( ( directive ) => {
@@ -599,6 +611,9 @@ function genProps(el: ElementNode | ComponentNode): void {
599
611
} )
600
612
} )
601
613
ctx . write ( '])' )
614
+ if ( isPlainElementNode ( el ) ) {
615
+ ctx . typeGuards . pop ( )
616
+ }
602
617
}
603
618
604
619
if ( isStaticExpression ( prop . arg ) ) {
@@ -644,12 +659,12 @@ function genProps(el: ElementNode | ComponentNode): void {
644
659
type . value ?. content === 'radio' )
645
660
) {
646
661
isCheckbox = true
647
- ctx . write ( 'checked' , prop . nameLoc )
662
+ ctx . write ( 'checked' , prop . nameLoc , true )
648
663
} else {
649
- ctx . write ( 'value' , prop . nameLoc )
664
+ ctx . write ( 'value' , prop . nameLoc , true )
650
665
}
651
666
} else {
652
- ctx . write ( 'modelValue' , prop . nameLoc )
667
+ ctx . write ( 'modelValue' , prop . nameLoc , true )
653
668
}
654
669
655
670
ctx . write ( '={' )
@@ -674,7 +689,7 @@ function genProps(el: ElementNode | ComponentNode): void {
674
689
}
675
690
ctx . write ( '}' )
676
691
} else if ( isStaticExpression ( prop . arg ) ) {
677
- genExpressionNode ( prop . arg )
692
+ ctx . write ( prop . arg . content , prop . arg . loc )
678
693
ctx . write ( '={' )
679
694
genExp ( )
680
695
ctx . write ( '}' )
@@ -737,15 +752,14 @@ function genVBindDirective(
737
752
ctx . write ( ': true' )
738
753
}
739
754
ctx . write ( '})}' )
755
+ } else if ( prop . exp == null ) {
756
+ ctx . write ( ' ' , prop . loc )
740
757
} else {
741
758
ctx . write ( '{...(' )
742
759
if ( prop . exp != null ) {
743
760
genExpressionNode ( prop . exp )
744
761
} else {
745
- ctx . write (
746
- annotations . missingExpression ,
747
- createLoc ( prop . loc , prop . loc . source . length ) ,
748
- )
762
+ ctx . write ( ' ' , createLoc ( prop . loc , prop . loc . source . length ) )
749
763
}
750
764
ctx . write ( ')}' )
751
765
}
@@ -756,12 +770,9 @@ function genTextNode(node: TextNode): void {
756
770
}
757
771
758
772
function genInterpolationNode ( node : InterpolationNode ) : void {
759
- ctx . write ( '{' , node . loc )
773
+ ctx . write ( ' {' , node . loc )
760
774
genExpressionNode ( node . content )
761
- ctx . write (
762
- '}' ,
763
- createLoc ( node . loc , node . content . loc . end . offset - node . loc . start . offset ) ,
764
- )
775
+ ctx . write ( '} ' , sliceLoc ( node . loc , - 2 ) )
765
776
}
766
777
767
778
function genExpressionNode ( node : ExpressionNode ) : void {
@@ -795,6 +806,7 @@ function genExpressionNodeAsFunction(node: ExpressionNode): void {
795
806
node . content . includes ( '$event' )
796
807
? ctx . write ( '($event) => {' ) . newLine ( )
797
808
: ctx . write ( '() => {' ) . newLine ( )
809
+ genTypeGuards ( )
798
810
genSimpleExpressionNode ( node )
799
811
ctx . newLine ( ) . write ( '}' )
800
812
}
0 commit comments