5
5
using Microsoft . CodeAnalysis . Text ;
6
6
using UnityUxmlGenerator . Captures ;
7
7
using UnityUxmlGenerator . Extensions ;
8
+ using UnityUxmlGenerator . Structs ;
8
9
9
10
namespace UnityUxmlGenerator ;
10
11
11
12
internal sealed partial class UxmlGenerator
12
13
{
14
+ private const string UnityColorTypeFullName = "global::UnityEngine.Color" ;
15
+ private const string UnityUiElementsFullName = "global::UnityEngine.UIElements.{0}" ;
16
+ private const string UxmlColorAttributeDescription = "UxmlColorAttributeDescription" ;
17
+
13
18
private static SourceText GenerateUxmlTraits ( GeneratorExecutionContext context , UxmlTraitsCapture capture )
14
19
{
15
20
var @class = ClassDeclaration ( capture . ClassName ) . AddModifiers ( Token ( SyntaxKind . PartialKeyword ) ) ;
@@ -27,7 +32,7 @@ private static MemberDeclarationSyntax GetTraitsClass(GeneratorExecutionContext
27
32
ClassDeclaration ( "UxmlTraits" )
28
33
. WithModifiers ( TokenList ( Token ( SyntaxKind . PublicKeyword ) , Token ( SyntaxKind . NewKeyword ) ) )
29
34
. WithBaseList ( BaseList ( SingletonSeparatedList < BaseTypeSyntax > ( uxmlTraitsBaseList ) ) )
30
- . WithMembers ( List ( GetTraitsClassMembers ( capture ) ) ) ;
35
+ . WithMembers ( List ( GetTraitsClassMembers ( context , capture ) ) ) ;
31
36
}
32
37
33
38
private static string GetBaseClassName ( GeneratorExecutionContext context , UxmlTraitsCapture capture )
@@ -56,9 +61,10 @@ private static string GetBaseClassName(GeneratorExecutionContext context, UxmlTr
56
61
return string . Empty ;
57
62
}
58
63
59
- private static IEnumerable < MemberDeclarationSyntax > GetTraitsClassMembers ( UxmlTraitsCapture capture )
64
+ private static IEnumerable < MemberDeclarationSyntax > GetTraitsClassMembers ( GeneratorExecutionContext context ,
65
+ UxmlTraitsCapture capture )
60
66
{
61
- var members = new List < MemberDeclarationSyntax > ( GetAttributeFields ( capture ) ) ;
67
+ var members = new List < MemberDeclarationSyntax > ( GetAttributeFields ( context , capture ) ) ;
62
68
63
69
var initMethodBody = new List < StatementSyntax >
64
70
{
@@ -88,13 +94,13 @@ private static IEnumerable<MemberDeclarationSyntax> GetTraitsClassMembers(UxmlTr
88
94
. WithParameterList ( ParameterList ( SeparatedList < ParameterSyntax > ( new SyntaxNodeOrToken [ ]
89
95
{
90
96
Parameter ( Identifier ( "visualElement" ) )
91
- . WithType ( IdentifierName ( "global::UnityEngine.UIElements. VisualElement") ) ,
97
+ . WithType ( IdentifierName ( string . Format ( UnityUiElementsFullName , " VisualElement") ) ) ,
92
98
Token ( SyntaxKind . CommaToken ) ,
93
99
Parameter ( Identifier ( "bag" ) )
94
- . WithType ( IdentifierName ( "global::UnityEngine.UIElements. IUxmlAttributes") ) ,
100
+ . WithType ( IdentifierName ( string . Format ( UnityUiElementsFullName , " IUxmlAttributes") ) ) ,
95
101
Token ( SyntaxKind . CommaToken ) ,
96
102
Parameter ( Identifier ( "context" ) )
97
- . WithType ( IdentifierName ( "global::UnityEngine.UIElements. CreationContext") )
103
+ . WithType ( IdentifierName ( string . Format ( UnityUiElementsFullName , " CreationContext") ) )
98
104
} ) ) )
99
105
. WithBody ( Block ( initMethodBody ) ) ;
100
106
@@ -103,44 +109,118 @@ private static IEnumerable<MemberDeclarationSyntax> GetTraitsClassMembers(UxmlTr
103
109
return ProcessMemberDeclarations ( members ) ;
104
110
}
105
111
106
- private static IEnumerable < MemberDeclarationSyntax > GetAttributeFields ( UxmlTraitsCapture capture )
112
+ private static IEnumerable < MemberDeclarationSyntax > GetAttributeFields ( GeneratorExecutionContext context ,
113
+ UxmlTraitsCapture capture )
107
114
{
108
115
var fields = new List < MemberDeclarationSyntax > ( ) ;
109
116
110
117
foreach ( var ( property , uxmlAttributeDefaultValue ) in capture . Properties )
111
118
{
112
- var propertyName = property . GetName ( ) ;
119
+ fields . Add ( GetAttributeFieldDeclaration ( GetAttributeInfo ( context , property , uxmlAttributeDefaultValue ) ) ) ;
120
+ }
113
121
114
- var fieldName = propertyName . ToPrivateFieldName ( ) ;
122
+ return fields ;
123
+ }
115
124
116
- var attributeType = "UxmlStringAttributeDescription" ;
117
- var attributeUxmlName = propertyName . ToDashCase ( ) ;
118
- var attributeDefaultValue = uxmlAttributeDefaultValue ?? string . Empty ;
125
+ private static UxmlAttributeInfo GetAttributeInfo ( GeneratorExecutionContext context ,
126
+ PropertyDeclarationSyntax property , string ? uxmlAttributeDefaultValue )
127
+ {
128
+ var propertyName = property . GetName ( ) ;
129
+
130
+ var info = new UxmlAttributeInfo
131
+ {
132
+ TypeIdentifier = GetPropertyTypeIdentifier ( context , property , out var typeSyntax ) ,
133
+ PrivateFieldName = propertyName . ToPrivateFieldName ( ) ,
134
+ AttributeUxmlName = propertyName . ToDashCase ( )
135
+ } ;
119
136
120
- fields . Add ( GetAttributeFieldDeclaration ( attributeType , fieldName , attributeUxmlName ,
121
- attributeDefaultValue ) ) ;
137
+ if ( uxmlAttributeDefaultValue is null || typeSyntax is null )
138
+ {
139
+ info . DefaultValueAssignmentExpression =
140
+ LiteralExpression ( SyntaxKind . DefaultLiteralExpression , Token ( SyntaxKind . DefaultKeyword ) ) ;
141
+ return info ;
122
142
}
123
143
124
- return fields ;
144
+ if ( typeSyntax . IsBoolType ( ) )
145
+ {
146
+ info . DefaultValueAssignmentExpression = IdentifierName ( uxmlAttributeDefaultValue ) ;
147
+ return info ;
148
+ }
149
+
150
+ if ( typeSyntax . IsStringType ( ) )
151
+ {
152
+ info . DefaultValueAssignmentExpression = LiteralExpression ( SyntaxKind . StringLiteralExpression ,
153
+ Literal ( uxmlAttributeDefaultValue ) ) ;
154
+ return info ;
155
+ }
156
+
157
+ if ( typeSyntax . IsNumericType ( ) )
158
+ {
159
+ info . DefaultValueAssignmentExpression = LiteralExpression ( SyntaxKind . NumericLiteralExpression ,
160
+ Literal ( uxmlAttributeDefaultValue , uxmlAttributeDefaultValue ) ) ;
161
+ return info ;
162
+ }
163
+
164
+ if ( info . TypeIdentifier == UxmlColorAttributeDescription )
165
+ {
166
+ info . DefaultValueAssignmentExpression = IdentifierName ( $ "global::UnityEngine.{ uxmlAttributeDefaultValue } ") ;
167
+ return info ;
168
+ }
169
+
170
+ info . DefaultValueAssignmentExpression = IdentifierName ( uxmlAttributeDefaultValue ) ;
171
+ return info ;
172
+ }
173
+
174
+ private static string GetPropertyTypeIdentifier ( GeneratorExecutionContext context ,
175
+ BasePropertyDeclarationSyntax property , out TypeSyntax ? typeSyntax )
176
+ {
177
+ switch ( property . Type )
178
+ {
179
+ case PredefinedTypeSyntax predefinedType :
180
+ {
181
+ var propertyTypeIdentifier = predefinedType . Keyword . Text . FirstCharToUpper ( ) ;
182
+
183
+ typeSyntax = predefinedType ;
184
+
185
+ return $ "Uxml{ propertyTypeIdentifier } AttributeDescription";
186
+ }
187
+
188
+ case IdentifierNameSyntax customTypeSyntax :
189
+ {
190
+ var type = customTypeSyntax . Identifier . Text ;
191
+ var typeNamespace = customTypeSyntax . GetTypeNamespace ( context ) ;
192
+ var propertyTypeText = $ "global::{ typeNamespace } .{ type } ";
193
+
194
+ typeSyntax = customTypeSyntax ;
195
+
196
+ return propertyTypeText == UnityColorTypeFullName
197
+ ? UxmlColorAttributeDescription
198
+ : $ "UxmlEnumAttributeDescription<{ propertyTypeText } >";
199
+ }
200
+
201
+ default :
202
+ typeSyntax = default ;
203
+ return property . Type . GetText ( ) . ToString ( ) . Trim ( ) ;
204
+ }
125
205
}
126
206
127
- private static FieldDeclarationSyntax GetAttributeFieldDeclaration ( string attributeType , string fieldName ,
128
- string attributeName , string attributeDefaultValue )
207
+ private static FieldDeclarationSyntax GetAttributeFieldDeclaration ( UxmlAttributeInfo attributeInfo )
129
208
{
130
209
return
131
- FieldDeclaration ( VariableDeclaration ( IdentifierName ( $ "global::UnityEngine.UIElements.{ attributeType } ") )
132
- . WithVariables ( SingletonSeparatedList ( VariableDeclarator ( Identifier ( fieldName ) )
210
+ FieldDeclaration ( VariableDeclaration (
211
+ IdentifierName ( string . Format ( UnityUiElementsFullName , attributeInfo . TypeIdentifier ) ) )
212
+ . WithVariables ( SingletonSeparatedList ( VariableDeclarator ( Identifier ( attributeInfo . PrivateFieldName ) )
133
213
. WithInitializer ( EqualsValueClause ( ImplicitObjectCreationExpression ( )
134
214
. WithInitializer ( InitializerExpression ( SyntaxKind . ObjectInitializerExpression ,
135
215
SeparatedList < ExpressionSyntax > ( new SyntaxNodeOrToken [ ]
136
216
{
137
217
AssignmentExpression ( SyntaxKind . SimpleAssignmentExpression ,
138
- IdentifierName ( "name" ) ,
139
- LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( attributeName ) ) ) ,
218
+ IdentifierName ( "name" ) ,
219
+ LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( attributeInfo . AttributeUxmlName ) ) ) ,
140
220
Token ( SyntaxKind . CommaToken ) ,
141
221
AssignmentExpression ( SyntaxKind . SimpleAssignmentExpression ,
142
- IdentifierName ( "defaultValue" ) ,
143
- LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( attributeDefaultValue ) ) )
222
+ IdentifierName ( "defaultValue" ) ,
223
+ attributeInfo . DefaultValueAssignmentExpression )
144
224
} ) ) ) ) ) ) ) )
145
225
. WithModifiers ( TokenList ( Token ( SyntaxKind . PrivateKeyword ) , Token ( SyntaxKind . ReadOnlyKeyword ) ) ) ;
146
226
}
0 commit comments