@@ -554,232 +554,118 @@ struct BridgeJSLink {
554
554
func renderExportedEnum( _ enumDefinition: ExportedEnum ) throws -> ( js: [ String ] , dts: [ String ] ) {
555
555
var jsLines : [ String ] = [ ]
556
556
var dtsLines : [ String ] = [ ]
557
- let style : EnumEmitStyle = enumDefinition. emitStyle
557
+ let scope = JSGlueVariableScope ( )
558
+ let cleanup = CodeFragmentPrinter ( )
559
+ let printer = CodeFragmentPrinter ( )
558
560
559
561
switch enumDefinition. enumType {
560
562
case . simple:
561
- jsLines. append ( " const \( enumDefinition. name) = { " )
562
- for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
563
- let caseName = enumCase. name. capitalizedFirstLetter
564
- jsLines. append ( " \( caseName) : \( index) , " . indent ( count: 4 ) )
565
- }
566
- jsLines. append ( " }; " )
567
- jsLines. append ( " " )
568
-
569
- if enumDefinition. namespace == nil {
570
- switch style {
571
- case . tsEnum:
572
- dtsLines. append ( " export enum \( enumDefinition. name) { " )
573
- for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
574
- let caseName = enumCase. name. capitalizedFirstLetter
575
- dtsLines. append ( " \( caseName) = \( index) , " . indent ( count: 4 ) )
576
- }
577
- dtsLines. append ( " } " )
578
- dtsLines. append ( " " )
579
- case . const:
580
- dtsLines. append ( " export const \( enumDefinition. name) : { " )
581
- for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
582
- let caseName = enumCase. name. capitalizedFirstLetter
583
- dtsLines. append ( " readonly \( caseName) : \( index) ; " . indent ( count: 4 ) )
584
- }
585
- dtsLines. append ( " }; " )
586
- dtsLines. append (
587
- " export type \( enumDefinition. name) = typeof \( enumDefinition. name) [keyof typeof \( enumDefinition. name) ]; "
588
- )
589
- dtsLines. append ( " " )
590
- }
591
- }
563
+ let fragment = IntrinsicJSFragment . simpleEnumHelper ( enumDefinition: enumDefinition)
564
+ _ = fragment. printCode ( [ enumDefinition. name] , scope, printer, cleanup)
565
+
566
+ jsLines. append ( contentsOf: printer. lines)
592
567
case . rawValue:
593
- guard let rawType = enumDefinition . rawType else {
568
+ guard enumDefinition . rawType != nil else {
594
569
throw BridgeJSLinkError ( message: " Raw value enum \( enumDefinition. name) is missing rawType " )
595
570
}
596
571
597
- jsLines. append ( " const \( enumDefinition. name) = { " )
598
- for enumCase in enumDefinition. cases {
599
- let caseName = enumCase. name. capitalizedFirstLetter
600
- let rawValue = enumCase. rawValue ?? enumCase. name
601
- let formattedValue : String
602
-
603
- if let rawTypeEnum = SwiftEnumRawType . from ( rawType) {
604
- switch rawTypeEnum {
605
- case . string:
606
- formattedValue = " \" \( rawValue) \" "
607
- case . bool:
608
- formattedValue = rawValue. lowercased ( ) == " true " ? " true " : " false "
609
- case . float, . double:
610
- formattedValue = rawValue
611
- default :
612
- formattedValue = rawValue
613
- }
614
- } else {
615
- formattedValue = rawValue
616
- }
572
+ let fragment = IntrinsicJSFragment . rawValueEnumHelper ( enumDefinition: enumDefinition)
573
+ _ = fragment. printCode ( [ enumDefinition. name] , scope, printer, cleanup)
617
574
618
- jsLines. append ( " \( caseName) : \( formattedValue) , " . indent ( count: 4 ) )
619
- }
620
- jsLines. append ( " }; " )
621
- jsLines. append ( " " )
622
-
623
- if enumDefinition. namespace == nil {
624
- switch style {
625
- case . tsEnum:
626
- dtsLines. append ( " export enum \( enumDefinition. name) { " )
627
- for enumCase in enumDefinition. cases {
628
- let caseName = enumCase. name. capitalizedFirstLetter
575
+ jsLines. append ( contentsOf: printer. lines)
576
+ case . associatedValue:
577
+ let fragment = IntrinsicJSFragment . associatedValueEnumHelper ( enumDefinition: enumDefinition)
578
+ _ = fragment. printCode ( [ enumDefinition. name] , scope, printer, cleanup)
579
+
580
+ jsLines. append ( contentsOf: printer. lines)
581
+ case . namespace:
582
+ break
583
+ }
584
+
585
+ if enumDefinition. namespace == nil {
586
+ dtsLines. append ( contentsOf: generateDeclarations ( enumDefinition: enumDefinition) )
587
+ }
588
+
589
+ return ( jsLines, dtsLines)
590
+ }
591
+
592
+ private func generateDeclarations( enumDefinition: ExportedEnum ) -> [ String ] {
593
+ let printer = CodeFragmentPrinter ( )
594
+
595
+ switch enumDefinition. emitStyle {
596
+ case . tsEnum:
597
+ switch enumDefinition. enumType {
598
+ case . simple, . rawValue:
599
+ printer. write ( " export enum \( enumDefinition. name) { " )
600
+ printer. indent ( )
601
+ for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
602
+ let caseName = enumCase. name. capitalizedFirstLetter
603
+ let value : String
604
+
605
+ switch enumDefinition. enumType {
606
+ case . simple:
607
+ value = " \( index) "
608
+ case . rawValue:
629
609
let rawValue = enumCase. rawValue ?? enumCase. name
630
- let formattedValue : String
631
- switch rawType {
632
- case " String " : formattedValue = " \" \( rawValue) \" "
633
- case " Bool " : formattedValue = rawValue. lowercased ( ) == " true " ? " true " : " false "
634
- case " Float " , " Double " : formattedValue = rawValue
635
- default : formattedValue = rawValue
636
- }
637
- dtsLines. append ( " \( caseName) = \( formattedValue) , " . indent ( count: 4 ) )
610
+ value = SwiftEnumRawType . formatValue ( rawValue, rawType: enumDefinition. rawType ?? " " )
611
+ case . associatedValue, . namespace:
612
+ continue
638
613
}
639
- dtsLines. append ( " } " )
640
- dtsLines. append ( " " )
641
- case . const:
642
- dtsLines. append ( " export const \( enumDefinition. name) : { " )
643
- for enumCase in enumDefinition. cases {
644
- let caseName = enumCase. name. capitalizedFirstLetter
645
- let rawValue = enumCase. rawValue ?? enumCase. name
646
- let formattedValue : String
647
-
648
- switch rawType {
649
- case " String " :
650
- formattedValue = " \" \( rawValue) \" "
651
- case " Bool " :
652
- formattedValue = rawValue. lowercased ( ) == " true " ? " true " : " false "
653
- case " Float " , " Double " :
654
- formattedValue = rawValue
655
- default :
656
- formattedValue = rawValue
657
- }
658
614
659
- dtsLines. append ( " readonly \( caseName) : \( formattedValue) ; " . indent ( count: 4 ) )
660
- }
661
- dtsLines. append ( " }; " )
662
- dtsLines. append (
663
- " export type \( enumDefinition. name) = typeof \( enumDefinition. name) [keyof typeof \( enumDefinition. name) ]; "
664
- )
665
- dtsLines. append ( " " )
615
+ printer. write ( " \( caseName) = \( value) , " )
666
616
}
617
+ printer. unindent ( )
618
+ printer. write ( " } " )
619
+ printer. write ( " " )
620
+ case . associatedValue, . namespace:
621
+ break
667
622
}
668
- case . associatedValue:
669
- // Use the new IntrinsicJSFragment for associated value payload handling
670
- jsLines. append ( " const \( enumDefinition. name) = { " )
671
- jsLines. append ( " Tag: { " . indent ( count: 4 ) )
672
- for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
673
- let caseName = enumCase. name. capitalizedFirstLetter
674
- jsLines. append ( " \( caseName) : \( index) , " . indent ( count: 8 ) )
675
- }
676
- jsLines. append ( " } " . indent ( count: 4 ) )
677
- jsLines. append ( " }; " )
678
- jsLines. append ( " " )
679
- jsLines. append ( " const __bjs_create \( enumDefinition. name) Helpers = () => { " )
680
- jsLines. append (
681
- " return ( \( JSGlueVariableScope . reservedTmpParamInts) , \( JSGlueVariableScope . reservedTmpParamF32s) , \( JSGlueVariableScope . reservedTmpParamF64s) , textEncoder, \( JSGlueVariableScope . reservedSwift) ) => ({ "
682
- . indent (
683
- count: 4
684
- )
685
- )
686
623
687
- jsLines. append ( " lower: (value) => { " . indent ( count: 8 ) )
688
- jsLines. append ( " const enumTag = value.tag; " . indent ( count: 12 ) )
689
- jsLines. append ( " switch (enumTag) { " . indent ( count: 12 ) )
690
- enumDefinition. cases. forEach { enumCase in
691
- let caseName = enumCase. name. capitalizedFirstLetter
692
- if enumCase. associatedValues. isEmpty {
693
- jsLines. append ( " case \( enumDefinition. name) .Tag. \( caseName) : { " . indent ( count: 16 ) )
694
- jsLines. append ( " const cleanup = undefined; " . indent ( count: 20 ) )
695
- jsLines. append (
696
- " return { caseId: \( enumDefinition. name) .Tag. \( caseName) , cleanup }; "
697
- . indent ( count: 20 )
698
- )
699
- jsLines. append ( " } " . indent ( count: 16 ) )
700
- } else {
701
- let scope = JSGlueVariableScope ( )
702
- let cleanup = CodeFragmentPrinter ( )
703
- let printer = CodeFragmentPrinter ( )
704
- cleanup. indent ( )
705
-
706
- let fragment = IntrinsicJSFragment . associatedValuePushPayload ( enumCase: enumCase)
707
- _ = fragment. printCode ( [ " value " , enumDefinition. name, caseName] , scope, printer, cleanup)
708
-
709
- jsLines. append ( " case \( enumDefinition. name) .Tag. \( caseName) : { " . indent ( count: 16 ) )
710
- jsLines. append ( contentsOf: printer. lines. map { $0. indent ( count: 20 ) } )
711
- jsLines. append ( " } " . indent ( count: 16 ) )
624
+ case . const:
625
+ switch enumDefinition. enumType {
626
+ case . simple:
627
+ printer. write ( " export const \( enumDefinition. name) : { " )
628
+ printer. indent ( )
629
+ for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
630
+ let caseName = enumCase. name. capitalizedFirstLetter
631
+ printer. write ( " readonly \( caseName) : \( index) ; " )
712
632
}
713
- }
714
- jsLines . append (
715
- " default: throw new Error( \" Unknown \( enumDefinition . name ) tag: \" + String(enumTag)); " . indent (
716
- count : 16
633
+ printer . unindent ( )
634
+ printer . write ( " }; " )
635
+ printer . write (
636
+ " export type \( enumDefinition . name ) = typeof \( enumDefinition . name ) [keyof typeof \( enumDefinition . name ) ]; "
717
637
)
718
- )
719
- jsLines. append ( " } " . indent ( count: 12 ) )
720
- jsLines. append ( " }, " . indent ( count: 8 ) )
721
-
722
- jsLines. append (
723
- " raise: ( \( JSGlueVariableScope . reservedTmpRetTag) , \( JSGlueVariableScope . reservedTmpRetStrings) , \( JSGlueVariableScope . reservedTmpRetInts) , \( JSGlueVariableScope . reservedTmpRetF32s) , \( JSGlueVariableScope . reservedTmpRetF64s) ) => { "
724
- . indent (
725
- count: 8
726
- )
727
- )
728
- jsLines. append ( " const tag = tmpRetTag | 0; " . indent ( count: 12 ) )
729
- jsLines. append ( " switch (tag) { " . indent ( count: 12 ) )
730
- enumDefinition. cases. forEach { enumCase in
731
- let caseName = enumCase. name. capitalizedFirstLetter
732
- if enumCase. associatedValues. isEmpty {
733
- jsLines. append (
734
- " case \( enumDefinition. name) .Tag. \( caseName) : return { tag: \( enumDefinition. name) .Tag. \( caseName) }; "
735
- . indent ( count: 16 )
736
- )
737
- } else {
738
- var fieldPairs : [ String ] = [ ]
739
- let scope = JSGlueVariableScope ( )
740
- let printer = CodeFragmentPrinter ( )
741
- let cleanup = CodeFragmentPrinter ( )
742
- // Use the new IntrinsicJSFragment for associated value payload handling
743
- for (associatedValueIndex, associatedValue) in enumCase. associatedValues. enumerated ( ) . reversed ( ) {
744
- let prop = associatedValue. label ?? " param \( associatedValueIndex) "
745
- let fragment = IntrinsicJSFragment . associatedValuePopPayload ( type: associatedValue. type)
746
-
747
- let result = fragment. printCode ( [ ] , scope, printer, cleanup)
748
- let varName = result. first ?? " value_ \( associatedValueIndex) "
749
-
750
- fieldPairs. append ( " \( prop) : \( varName) " )
751
- }
752
-
753
- jsLines. append ( " case \( enumDefinition. name) .Tag. \( caseName) : { " . indent ( count: 16 ) )
754
- jsLines. append ( contentsOf: printer. lines. map { $0. indent ( count: 20 ) } )
755
- jsLines. append (
756
- " return { tag: \( enumDefinition. name) .Tag. \( caseName) , \( fieldPairs. reversed ( ) . joined ( separator: " , " ) ) }; "
757
- . indent ( count: 20 )
758
- )
759
- jsLines. append ( " } " . indent ( count: 16 ) )
638
+ printer. write ( " " )
639
+ case . rawValue:
640
+ printer. write ( " export const \( enumDefinition. name) : { " )
641
+ printer. indent ( )
642
+ for enumCase in enumDefinition. cases {
643
+ let caseName = enumCase. name. capitalizedFirstLetter
644
+ let rawValue = enumCase. rawValue ?? enumCase. name
645
+ let formattedValue = SwiftEnumRawType . formatValue ( rawValue, rawType: enumDefinition. rawType ?? " " )
646
+ printer. write ( " readonly \( caseName) : \( formattedValue) ; " )
760
647
}
761
- }
762
- jsLines. append (
763
- " default: throw new Error( \" Unknown \( enumDefinition. name) tag returned from Swift: \" + String(tag)); "
764
- . indent (
765
- count: 16
766
- )
767
- )
768
- jsLines. append ( " } " . indent ( count: 12 ) )
769
- jsLines. append ( " } " . indent ( count: 8 ) )
770
- jsLines. append ( " }); " . indent ( count: 4 ) )
771
- jsLines. append ( " }; " )
772
-
773
- if enumDefinition. namespace == nil {
774
- dtsLines. append ( " export const \( enumDefinition. name) : { " )
775
- dtsLines. append ( " readonly Tag: { " . indent ( count: 4 ) )
648
+ printer. unindent ( )
649
+ printer. write ( " }; " )
650
+ printer. write (
651
+ " export type \( enumDefinition. name) = typeof \( enumDefinition. name) [keyof typeof \( enumDefinition. name) ]; "
652
+ )
653
+ printer. write ( " " )
654
+ case . associatedValue:
655
+ printer. write ( " export const \( enumDefinition. name) : { " )
656
+ printer. indent ( )
657
+ printer. write ( " readonly Tag: { " )
658
+ printer. indent ( )
776
659
for (index, enumCase) in enumDefinition. cases. enumerated ( ) {
777
660
let caseName = enumCase. name. capitalizedFirstLetter
778
- dtsLines . append ( " readonly \( caseName) : \( index) ; " . indent ( count : 8 ) )
661
+ printer . write ( " readonly \( caseName) : \( index) ; " )
779
662
}
780
- dtsLines. append ( " }; " . indent ( count: 4 ) )
781
- dtsLines. append ( " }; " )
782
- dtsLines. append ( " " )
663
+ printer. unindent ( )
664
+ printer. write ( " }; " )
665
+ printer. unindent ( )
666
+ printer. write ( " }; " )
667
+ printer. write ( " " )
668
+
783
669
var unionParts : [ String ] = [ ]
784
670
for enumCase in enumDefinition. cases {
785
671
if enumCase. associatedValues. isEmpty {
@@ -790,32 +676,26 @@ struct BridgeJSLink {
790
676
var fields : [ String ] = [
791
677
" tag: typeof \( enumDefinition. name) .Tag. \( enumCase. name. capitalizedFirstLetter) "
792
678
]
793
- for (associatedValueIndex, associatedValue) in enumCase. associatedValues
794
- . enumerated ( )
795
- {
679
+ for (associatedValueIndex, associatedValue) in enumCase. associatedValues. enumerated ( ) {
796
680
let prop = associatedValue. label ?? " param \( associatedValueIndex) "
797
- let ts : String
798
- switch associatedValue. type {
799
- case . string: ts = " string "
800
- case . bool: ts = " boolean "
801
- case . int, . float, . double: ts = " number "
802
- default : ts = " never "
803
- }
804
- fields. append ( " \( prop) : \( ts) " )
681
+ fields. append ( " \( prop) : \( associatedValue. type. tsType) " )
805
682
}
806
683
unionParts. append ( " { \( fields. joined ( separator: " ; " ) ) } " )
807
684
}
808
685
}
809
- dtsLines. append ( " export type \( enumDefinition. name) = " )
810
- dtsLines. append ( " " + unionParts. joined ( separator: " | " ) )
811
- dtsLines. append ( " " )
686
+
687
+ printer. write ( " export type \( enumDefinition. name) = " )
688
+ printer. write ( " " + unionParts. joined ( separator: " | " ) )
689
+ printer. write ( " " )
690
+ case . namespace:
691
+ break
812
692
}
813
- case . namespace:
814
- break
815
693
}
816
-
817
- return ( jsLines, dtsLines)
694
+ return printer. lines
818
695
}
696
+ }
697
+
698
+ extension BridgeJSLink {
819
699
820
700
func renderExportedFunction( function: ExportedFunction ) throws -> ( js: [ String ] , dts: [ String ] ) {
821
701
let thunkBuilder = ExportedThunkBuilder ( effects: function. effects)
@@ -1502,14 +1382,7 @@ struct BridgeJSLink {
1502
1382
. enumerated ( )
1503
1383
{
1504
1384
let prop = associatedValue. label ?? " param \( associatedValueIndex) "
1505
- let ts : String
1506
- switch associatedValue. type {
1507
- case . string: ts = " string "
1508
- case . bool: ts = " boolean "
1509
- case . int, . float, . double: ts = " number "
1510
- default : ts = " never "
1511
- }
1512
- fields. append ( " \( prop) : \( ts) " )
1385
+ fields. append ( " \( prop) : \( associatedValue. type. tsType) " )
1513
1386
}
1514
1387
unionParts. append ( " { \( fields. joined ( separator: " ; " ) ) } " )
1515
1388
}
0 commit comments