1
- namespace AgileObjects . ReadableExpressions . Extensions
1
+ using AgileObjects . ReadableExpressions . Translations ;
2
+
3
+ namespace AgileObjects . ReadableExpressions . Extensions
2
4
{
3
5
using System ;
4
6
using System . Collections ;
@@ -29,59 +31,120 @@ internal static string GetFriendlyName(this Type type, TranslationSettings trans
29
31
return null ;
30
32
}
31
33
34
+ var buffer = new TranslationBuffer ( type . FullName . Length ) ;
35
+
36
+ buffer . WriteFriendlyName ( type , translationSettings ) ;
37
+
38
+ return buffer . GetContent ( ) ;
39
+ }
40
+
41
+ internal static void WriteFriendlyName (
42
+ this TranslationBuffer buffer ,
43
+ Type type ,
44
+ TranslationSettings settings )
45
+ {
46
+ if ( type . FullName == null )
47
+ {
48
+ // An open generic parameter Type:
49
+ return ;
50
+ }
51
+
32
52
if ( type . IsArray )
33
53
{
34
- return type . GetElementType ( ) . GetFriendlyName ( translationSettings ) + "[]" ;
54
+ buffer . WriteFriendlyName ( type . GetElementType ( ) , settings ) ;
55
+ buffer . WriteToTranslation ( "[]" ) ;
56
+ return ;
35
57
}
36
58
37
59
if ( ! type . IsGenericType ( ) )
38
60
{
39
- var substitutedTypeName = type . FullName . GetSubstitutionOrNull ( ) ;
40
- var qualifiedTypeName = substitutedTypeName ?? type . Name ;
61
+ var substitutedTypeName = type . GetSubstitutionOrNull ( ) ;
41
62
42
63
if ( type . IsNested )
43
64
{
44
- return type . DeclaringType . GetFriendlyName ( translationSettings ) + "." + qualifiedTypeName ;
65
+ buffer . WriteFriendlyName ( type . DeclaringType , settings ) ;
66
+ buffer . WriteToTranslation ( '.' ) ;
67
+ buffer . WriteToTranslation ( substitutedTypeName ?? type . Name ) ;
68
+ return ;
69
+ }
70
+
71
+ if ( substitutedTypeName != null )
72
+ {
73
+ buffer . WriteToTranslation ( substitutedTypeName ) ;
74
+ return ;
45
75
}
46
76
47
- return ( substitutedTypeName == null )
48
- ? GetFinalisedTypeName ( type , qualifiedTypeName , translationSettings )
49
- : qualifiedTypeName ;
77
+ buffer . WriteTypeNamespaceIfRequired ( type , settings ) ;
78
+ buffer . WriteToTranslation ( type . Name ) ;
79
+ return ;
50
80
}
51
81
52
82
Type underlyingNullableType ;
53
83
54
- if ( ( underlyingNullableType = Nullable . GetUnderlyingType ( type ) ) ! = null )
84
+ if ( ( underlyingNullableType = Nullable . GetUnderlyingType ( type ) ) = = null )
55
85
{
56
- return underlyingNullableType . GetFriendlyName ( translationSettings ) + "?" ;
86
+ buffer . WriteGenericTypeName ( type , settings ) ;
87
+ return ;
57
88
}
58
89
59
- return GetGenericTypeName ( type , translationSettings ) ;
90
+ buffer . WriteFriendlyName ( underlyingNullableType , settings ) ;
91
+ buffer . WriteToTranslation ( '?' ) ;
60
92
}
61
93
62
- private static string GetGenericTypeName ( Type genericType , TranslationSettings settings )
94
+ private static void WriteTypeNamespaceIfRequired (
95
+ this TranslationBuffer buffer ,
96
+ Type type ,
97
+ TranslationSettings settings )
98
+ {
99
+ if ( ! settings . FullyQualifyTypeNames || ( type . Namespace == null ) )
100
+ {
101
+ return ;
102
+ }
103
+
104
+ buffer . WriteToTranslation ( type . Namespace ) ;
105
+ buffer . WriteToTranslation ( '.' ) ;
106
+ }
107
+
108
+ private static void WriteGenericTypeName (
109
+ this TranslationBuffer buffer ,
110
+ Type genericType ,
111
+ TranslationSettings settings )
63
112
{
64
113
var typeGenericTypeArguments = genericType . GetGenericTypeArguments ( ) ;
65
- var genericTypeName = GetClosedGenericTypeName ( genericType , ref typeGenericTypeArguments , settings ) ;
66
114
67
115
if ( ! genericType . IsNested )
68
116
{
69
- return GetFinalisedTypeName ( genericType , genericTypeName , settings ) ;
117
+ buffer . WriteTypeNamespaceIfRequired ( genericType , settings ) ;
118
+ buffer . WriteClosedGenericTypeName ( genericType , ref typeGenericTypeArguments , settings ) ;
119
+ return ;
70
120
}
71
121
122
+ var types = new List < Type > { genericType } ;
123
+
72
124
// ReSharper disable once PossibleNullReferenceException
73
125
while ( genericType . IsNested )
74
126
{
75
127
genericType = genericType . DeclaringType ;
76
- var parentTypeName = GetClosedGenericTypeName ( genericType , ref typeGenericTypeArguments , settings ) ;
77
-
78
- genericTypeName = parentTypeName + "." + genericTypeName ;
128
+ types . Add ( genericType ) ;
79
129
}
80
130
81
- return GetFinalisedTypeName ( genericType , genericTypeName , settings ) ;
131
+ buffer . WriteTypeNamespaceIfRequired ( genericType , settings ) ;
132
+
133
+ for ( var i = types . Count ; ; )
134
+ {
135
+ buffer . WriteClosedGenericTypeName ( types [ -- i ] , ref typeGenericTypeArguments , settings ) ;
136
+
137
+ if ( i == 0 )
138
+ {
139
+ return ;
140
+ }
141
+
142
+ buffer . WriteToTranslation ( '.' ) ;
143
+ }
82
144
}
83
145
84
- private static string GetClosedGenericTypeName (
146
+ private static void WriteClosedGenericTypeName (
147
+ this TranslationBuffer buffer ,
85
148
Type genericType ,
86
149
ref Type [ ] typeGenericTypeArguments ,
87
150
TranslationSettings settings )
@@ -92,7 +155,8 @@ private static string GetClosedGenericTypeName(
92
155
93
156
if ( backtickIndex == - 1 )
94
157
{
95
- return typeName ;
158
+ buffer . WriteToTranslation ( typeName ) ;
159
+ return ;
96
160
}
97
161
98
162
var numberOfParameters = int . Parse ( typeName . Substring ( backtickIndex + 1 ) ) ;
@@ -102,79 +166,93 @@ private static string GetClosedGenericTypeName(
102
166
if ( numberOfParameters == typeGenericTypeArguments . Length )
103
167
{
104
168
typeArguments = typeGenericTypeArguments ;
169
+ goto WriteName ;
105
170
}
106
- else
171
+
172
+ switch ( numberOfParameters )
107
173
{
108
- typeArguments = new Type [ numberOfParameters ] ;
109
- var numberOfRemainingTypeArguments = typeGenericTypeArguments . Length - numberOfParameters ;
110
- var typeGenericTypeArgumentsSubset = new Type [ numberOfRemainingTypeArguments ] ;
111
-
112
- Array . Copy (
113
- typeGenericTypeArguments ,
114
- numberOfRemainingTypeArguments ,
115
- typeArguments ,
116
- 0 ,
117
- numberOfParameters ) ;
118
-
119
- Array . Copy (
120
- typeGenericTypeArguments ,
121
- 0 ,
122
- typeGenericTypeArgumentsSubset ,
123
- 0 ,
124
- numberOfRemainingTypeArguments ) ;
125
-
126
- typeGenericTypeArguments = typeGenericTypeArgumentsSubset ;
174
+ case 1 :
175
+ typeArguments = new [ ] { typeGenericTypeArguments [ 0 ] } ;
176
+ break ;
177
+
178
+ case 2 :
179
+ typeArguments = new [ ] { typeGenericTypeArguments [ 0 ] , typeGenericTypeArguments [ 1 ] } ;
180
+ break ;
181
+
182
+ default :
183
+ typeArguments = new Type [ numberOfParameters ] ;
184
+
185
+ Array . Copy (
186
+ typeGenericTypeArguments ,
187
+ typeArguments ,
188
+ numberOfParameters ) ;
189
+
190
+ break ;
127
191
}
128
192
129
- return GetGenericTypeName ( genericType , numberOfParameters , typeArguments , settings ) ;
193
+ var numberOfRemainingTypeArguments = typeGenericTypeArguments . Length - numberOfParameters ;
194
+ var typeGenericTypeArgumentsSubset = new Type [ numberOfRemainingTypeArguments ] ;
195
+
196
+ Array . Copy (
197
+ typeGenericTypeArguments ,
198
+ numberOfParameters ,
199
+ typeGenericTypeArgumentsSubset ,
200
+ 0 ,
201
+ numberOfRemainingTypeArguments ) ;
202
+
203
+ typeGenericTypeArguments = typeGenericTypeArgumentsSubset ;
204
+
205
+ WriteName :
206
+ buffer . WriteGenericTypeName ( genericType , numberOfParameters , typeArguments , settings ) ;
130
207
}
131
208
132
- private static string GetGenericTypeName (
209
+ private static void WriteGenericTypeName (
210
+ this TranslationBuffer buffer ,
133
211
Type type ,
134
212
int numberOfParameters ,
135
213
IList < Type > typeArguments ,
136
214
TranslationSettings settings )
137
215
{
138
- var anonTypeIndex = 0 ;
139
-
140
216
var isAnonType =
141
217
type . Name . StartsWith ( '<' ) &&
142
- ( ( anonTypeIndex = type . Name . IndexOf ( "AnonymousType" , StringComparison . Ordinal ) ) != - 1 ) ;
218
+ ( type . Name . IndexOf ( "AnonymousType" , StringComparison . Ordinal ) ) != - 1 ;
143
219
144
220
if ( isAnonType && ( settings . AnonymousTypeNameFactory != null ) )
145
221
{
146
- return settings . AnonymousTypeNameFactory . Invoke ( type ) ;
222
+ buffer . WriteToTranslation ( settings . AnonymousTypeNameFactory . Invoke ( type ) ) ;
223
+ return ;
147
224
}
148
225
149
- var typeName = type . Name ;
226
+ string typeName ;
150
227
151
- var typeGenericTypeArgumentNames = typeArguments
152
- . ProjectToArray ( t => GetFriendlyName ( t , settings ) ) ;
153
-
154
- typeName = typeName . Replace (
155
- "`" + numberOfParameters ,
156
- "<" + typeGenericTypeArgumentNames . Join ( ", " ) + ">" ) ;
228
+ if ( isAnonType )
229
+ {
230
+ typeName = "AnonymousType" ;
231
+ }
232
+ else
233
+ {
234
+ var parameterCountIndex = type . Name . IndexOf ( "`" + numberOfParameters , StringComparison . Ordinal ) ;
235
+ typeName = type . Name . Substring ( 0 , parameterCountIndex ) ;
236
+ }
157
237
158
- return isAnonType ? GetAnonymousTypeName ( typeName , anonTypeIndex ) : typeName ;
159
- }
238
+ buffer . WriteToTranslation ( typeName ) ;
239
+ buffer . WriteToTranslation ( '<' ) ;
160
240
161
- private static string GetAnonymousTypeName ( string typeName , int anonTypeIndex )
162
- {
163
- typeName = typeName . Substring ( anonTypeIndex ) ;
241
+ for ( var i = 0 ; ; )
242
+ {
243
+ var typeArgument = typeArguments [ i ++ ] ;
164
244
165
- var trimStartIndex = "AnonymousType" . Length ;
166
- var argumentsStartIndex = typeName . IndexOf ( '<' ) ;
245
+ buffer . WriteFriendlyName ( typeArgument , settings ) ;
167
246
168
- typeName = typeName . Remove ( trimStartIndex , argumentsStartIndex - trimStartIndex ) ;
247
+ if ( i == typeArguments . Count )
248
+ {
249
+ break ;
250
+ }
169
251
170
- return typeName ;
171
- }
252
+ buffer . WriteToTranslation ( ", " ) ;
253
+ }
172
254
173
- private static string GetFinalisedTypeName ( Type type , string typeName , TranslationSettings settings )
174
- {
175
- return settings . FullyQualifyTypeNames && ( type . Namespace != null )
176
- ? type . Namespace + "." + typeName
177
- : typeName ;
255
+ buffer . WriteToTranslation ( '>' ) ;
178
256
}
179
257
180
258
/// <summary>
@@ -198,7 +276,7 @@ internal static string GetVariableNameInCamelCase(this Type type, TranslationSet
198
276
public static string GetVariableNameInPascalCase ( this Type type , Func < TranslationSettings , TranslationSettings > configuration = null )
199
277
=> GetVariableNameInPascalCase ( type , GetTranslationSettings ( configuration ) ) ;
200
278
201
- internal static string GetVariableNameInPascalCase ( this Type type , TranslationSettings settings )
279
+ private static string GetVariableNameInPascalCase ( this Type type , TranslationSettings settings )
202
280
=> GetVariableName ( type , settings ) . ToPascalCase ( ) ;
203
281
204
282
private static string GetVariableName ( Type type , TranslationSettings settings )
0 commit comments