@@ -643,6 +643,11 @@ function generateSwiftDataModel(entity: Entity, model: SemanticAppModel): string
643643 const relationshipFieldNames = new Set ( relationships . map ( r => camelCase ( r . fieldName ) ) ) ;
644644 const lines : string [ ] = [ ] ;
645645
646+ // SwiftData @Model macro conflicts with property named 'description' (CustomStringConvertible)
647+ // Rename to 'desc' in the SwiftData model and handle conversion in init/toModel
648+ const SWIFTDATA_RESERVED = new Set ( [ 'description' , 'hash' ] ) ;
649+ const sdFieldName = ( name : string ) => SWIFTDATA_RESERVED . has ( name ) ? `${ name } Text` : name ;
650+
646651 lines . push ( '@Model' ) ;
647652 lines . push ( `final class ${ storeName } {` ) ;
648653 if ( ! hasId ) { lines . push ( ' var id: UUID' ) ; lines . push ( '' ) ; }
@@ -661,7 +666,7 @@ function generateSwiftDataModel(entity: Entity, model: SemanticAppModel): string
661666 continue ;
662667 }
663668 }
664- lines . push ( ` var ${ field . name } : ${ swiftDataFieldType ( field . type ) } ` ) ;
669+ lines . push ( ` var ${ sdFieldName ( field . name ) } : ${ swiftDataFieldType ( field . type ) } ` ) ;
665670 }
666671
667672 // Init
@@ -671,15 +676,17 @@ function generateSwiftDataModel(entity: Entity, model: SemanticAppModel): string
671676 for ( const field of fields ) {
672677 if ( relationshipFieldNames . has ( field . name ) ) continue ;
673678 const sdType = swiftDataFieldType ( field . type ) ;
674- if ( field . isOptional ) initParams . push ( `${ field . name } : ${ sdType } = nil` ) ;
675- else if ( field . isId && sdType === 'UUID' ) initParams . push ( `${ field . name } : ${ sdType } = UUID()` ) ;
676- else initParams . push ( `${ field . name } : ${ sdType } ` ) ;
679+ const pName = sdFieldName ( field . name ) ;
680+ if ( field . isOptional ) initParams . push ( `${ pName } : ${ sdType } = nil` ) ;
681+ else if ( field . isId && sdType === 'UUID' ) initParams . push ( `${ pName } : ${ sdType } = UUID()` ) ;
682+ else initParams . push ( `${ pName } : ${ sdType } ` ) ;
677683 }
678684 lines . push ( ` init(${ initParams . join ( ', ' ) } ) {` ) ;
679685 if ( ! hasId ) lines . push ( ' self.id = id' ) ;
680686 for ( const field of fields ) {
681687 if ( relationshipFieldNames . has ( field . name ) ) continue ;
682- lines . push ( ` self.${ field . name } = ${ field . name } ` ) ;
688+ const pName = sdFieldName ( field . name ) ;
689+ lines . push ( ` self.${ pName } = ${ pName } ` ) ;
683690 }
684691 lines . push ( ' }' ) ;
685692
@@ -690,19 +697,18 @@ function generateSwiftDataModel(entity: Entity, model: SemanticAppModel): string
690697 if ( ! hasId ) convArgs . push ( 'id: model.id' ) ;
691698 for ( const field of fields ) {
692699 if ( relationshipFieldNames . has ( field . name ) ) continue ;
700+ const pName = sdFieldName ( field . name ) ;
693701 const sdType = swiftDataFieldType ( field . type ) ;
694702 if ( sdType . replace ( '?' , '' ) === 'Data' && field . type . replace ( '?' , '' ) !== 'Data' ) {
695- // Type needs JSON encoding: [String: String] → Data
696703 if ( field . isOptional ) {
697- convArgs . push ( `${ field . name } : (try? JSONEncoder().encode(model.${ field . name } )) ?? nil` ) ;
704+ convArgs . push ( `${ pName } : (try? JSONEncoder().encode(model.${ field . name } )) ?? nil` ) ;
698705 } else {
699- convArgs . push ( `${ field . name } : (try? JSONEncoder().encode(model.${ field . name } )) ?? Data()` ) ;
706+ convArgs . push ( `${ pName } : (try? JSONEncoder().encode(model.${ field . name } )) ?? Data()` ) ;
700707 }
701708 } else if ( sdType . replace ( '?' , '' ) === 'String' && field . type . replace ( '?' , '' ) !== 'String' && ! field . type . startsWith ( '[' ) ) {
702- // Non-string type stored as String
703- convArgs . push ( `${ field . name } : String(describing: model.${ field . name } )` ) ;
709+ convArgs . push ( `${ pName } : String(describing: model.${ field . name } )` ) ;
704710 } else {
705- convArgs . push ( `${ field . name } : model.${ field . name } ` ) ;
711+ convArgs . push ( `${ pName } : model.${ field . name } ` ) ;
706712 }
707713 }
708714 lines . push ( ` self.init(${ convArgs . join ( ', ' ) } )` ) ;
@@ -715,16 +721,16 @@ function generateSwiftDataModel(entity: Entity, model: SemanticAppModel): string
715721 if ( ! hasId ) modelArgs . push ( 'id: id' ) ;
716722 for ( const field of fields ) {
717723 if ( relationshipFieldNames . has ( field . name ) ) continue ;
724+ const pName = sdFieldName ( field . name ) ;
718725 const sdType = swiftDataFieldType ( field . type ) ;
719726 if ( sdType . replace ( '?' , '' ) === 'Data' && field . type . replace ( '?' , '' ) !== 'Data' ) {
720- // Data → decode back to original type
721727 if ( field . isOptional ) {
722- modelArgs . push ( `${ field . name } : ${ field . name } .flatMap { try? JSONDecoder().decode(${ field . type . replace ( '?' , '' ) } .self, from: $0) }` ) ;
728+ modelArgs . push ( `${ field . name } : ${ pName } .flatMap { try? JSONDecoder().decode(${ field . type . replace ( '?' , '' ) } .self, from: $0) }` ) ;
723729 } else {
724- modelArgs . push ( `${ field . name } : (try? JSONDecoder().decode(${ field . type } .self, from: ${ field . name } )) ?? ${ field . type } ()` ) ;
730+ modelArgs . push ( `${ field . name } : (try? JSONDecoder().decode(${ field . type } .self, from: ${ pName } )) ?? ${ field . type } ()` ) ;
725731 }
726732 } else {
727- modelArgs . push ( `${ field . name } : ${ field . name } ` ) ;
733+ modelArgs . push ( `${ field . name } : ${ pName } ` ) ;
728734 }
729735 }
730736 lines . push ( ` ${ structName } (${ modelArgs . join ( ', ' ) } )` ) ;
0 commit comments