9
9
using Microsoft . TypeSpec . Generator . Providers ;
10
10
using Microsoft . TypeSpec . Generator . Snippets ;
11
11
using Microsoft . TypeSpec . Generator . Statements ;
12
+ using System ;
12
13
using System . Collections . Generic ;
13
14
using System . Linq ;
14
15
using static Microsoft . TypeSpec . Generator . Snippets . Snippet ;
@@ -36,41 +37,55 @@ internal class FlattenPropertyVisitor : ScmLibraryVisitor
36
37
37
38
if ( type is ModelProvider model && _collectionTypeProperties . TryGetValue ( model , out var value ) )
38
39
{
39
- foreach ( var ( internalProperty , collectionProperties ) in value )
40
+ foreach ( var internalProperty in value )
40
41
{
41
- var innerCollectionProperties = collectionProperties . Select ( x => x . InnerProperty ) ;
42
- var initializationMethod = BuildInitializationMethod ( innerCollectionProperties , internalProperty , model ) ;
43
- var publicConstructor = model . Constructors . Single ( m => m . Signature . Modifiers . HasFlag ( MethodSignatureModifiers . Public ) ) ;
44
- var invokeInitialization = This . Invoke ( initializationMethod . Signature . Name ) . Terminate ( ) ;
42
+ var publicConstructor = model . Constructors . SingleOrDefault ( m => m . Signature . Modifiers . HasFlag ( MethodSignatureModifiers . Public ) ) ;
43
+ if ( publicConstructor is null )
44
+ {
45
+ continue ;
46
+ }
45
47
48
+ var internalPropertyTypeConstructor = ManagementClientGenerator . Instance . TypeFactory . CSharpTypeMap [ internalProperty . Type ] ! . Constructors . Single ( c => c . Signature . Modifiers . HasFlag ( MethodSignatureModifiers . Public ) ) ;
49
+ var initializationParameters = PopulateInitializationParameters ( publicConstructor , internalPropertyTypeConstructor ) ;
50
+ var initialization = internalProperty . Assign ( New . Instance ( internalProperty . Type , initializationParameters ) ) . Terminate ( ) ;
46
51
// If the property is a collection type, we need to ensure that it is initialized
47
52
if ( publicConstructor . BodyStatements is null )
48
53
{
49
- publicConstructor . Update ( bodyStatements : new List < MethodBodyStatement > { invokeInitialization } ) ;
54
+ publicConstructor . Update ( bodyStatements : new List < MethodBodyStatement > { initialization } ) ;
50
55
}
51
56
else
52
57
{
53
58
var body = publicConstructor . BodyStatements . ToList ( ) ;
54
- body . Add ( invokeInitialization ) ;
59
+ body . Add ( initialization ) ;
55
60
publicConstructor . Update ( bodyStatements : body ) ;
56
61
}
57
- model . Update ( methods : [ .. model . Methods , initializationMethod ] ) ;
58
62
}
59
63
}
60
64
61
65
return base . PostVisitType ( type ) ;
62
66
}
63
67
64
- internal const string s_initializationMethodName = "Initialize" ;
65
- private MethodProvider BuildInitializationMethod ( IEnumerable < PropertyProvider > collectionTypeProperties , PropertyProvider internalProperty , ModelProvider model )
68
+ private ValueExpression [ ] PopulateInitializationParameters ( ConstructorProvider publicConstructor , ConstructorProvider internalPropertyTypeConstructor )
66
69
{
67
- var signature = new MethodSignature ( $ "{ s_initializationMethodName } { internalProperty . Type . Name } ", null , MethodSignatureModifiers . Private , null , null , [ ] ) ;
68
- MethodBodyStatement [ ] body = [
69
- new IfStatement ( This . Property ( internalProperty . Name ) . Is ( Null ) )
70
- {
71
- internalProperty . Assign ( New . Instance ( internalProperty . Type , PropertyHelpers . PopulateCollectionProperties ( collectionTypeProperties ) ) ) . Terminate ( )
72
- } , ] ;
73
- return new MethodProvider ( signature , body , model ) ;
70
+ var parameters = new List < ValueExpression > ( ) ;
71
+ foreach ( var parameter in internalPropertyTypeConstructor . Signature . Parameters )
72
+ {
73
+ if ( parameter . Type . IsList )
74
+ {
75
+ parameters . Add ( New . Instance ( ManagementClientGenerator . Instance . TypeFactory . ListInitializationType . MakeGenericType ( parameter . Type . Arguments ) ) ) ;
76
+ }
77
+ else if ( parameter . Type . IsDictionary )
78
+ {
79
+ parameters . Add ( New . Instance ( ManagementClientGenerator . Instance . TypeFactory . DictionaryInitializationType . MakeGenericType ( parameter . Type . Arguments ) ) ) ;
80
+ }
81
+ else
82
+ {
83
+ var constructorParameter = publicConstructor . Signature . Parameters . Single ( p => p . Name . Equals ( parameter . Name , System . StringComparison . OrdinalIgnoreCase ) ) ;
84
+
85
+ parameters . Add ( constructorParameter ) ;
86
+ }
87
+ }
88
+ return parameters . ToArray ( ) ;
74
89
}
75
90
76
91
private void UpdateModelFactory ( ModelFactoryProvider modelFactory )
@@ -256,7 +271,7 @@ int GetAdditionalPropertyIndex()
256
271
// So that, we can use this to update the model factory methods later.
257
272
private readonly Dictionary < CSharpType , Dictionary < string , List < ( bool IsOverriddenValueType , PropertyProvider FlattenedProperty ) > > > _flattenedModelTypes = new ( ) ;
258
273
// TODO: Workadound to initialize all collection-type properties in all collection-type setters, remove this once we have lazy initializtion for collection-type properties
259
- private readonly Dictionary < ModelProvider , Dictionary < PropertyProvider , List < ( PropertyProvider FlattenedProperty , PropertyProvider InnerProperty ) > > > _collectionTypeProperties = new ( ) ;
274
+ private readonly Dictionary < ModelProvider , HashSet < PropertyProvider > > _collectionTypeProperties = new ( ) ;
260
275
private void FlattenProperties ( ModelProvider model )
261
276
{
262
277
var isFlattened = false ;
@@ -281,6 +296,7 @@ private void FlattenProperties(ModelProvider model)
281
296
282
297
foreach ( var innerProperty in innerProperties )
283
298
{
299
+ CollectFlattenTypeCollectionProperty ( property , innerProperty , model ) ;
284
300
// flatten the property to public and associate it with the internal property
285
301
var ( _, includeGetterNullCheck , _) = PropertyHelpers . GetFlags ( property , innerProperty ) ;
286
302
var flattenPropertyName = innerProperty . Name ; // TODO: handle name conflicts
@@ -304,7 +320,6 @@ private void FlattenProperties(ModelProvider model)
304
320
innerProperty . Attributes ) ;
305
321
306
322
flattenedProperties . Add ( ( isOverriddenValueType , flattenedProperty ) ) ;
307
- AddInternalSetterForFlattenTypeCollectionProperty ( property , innerProperty , flattenedProperty , model ) ;
308
323
}
309
324
// make the internalized properties internal
310
325
property . Update ( modifiers : property . Modifiers & ~ MethodSignatureModifiers . Public | MethodSignatureModifiers . Internal ) ;
@@ -322,28 +337,20 @@ private void FlattenProperties(ModelProvider model)
322
337
}
323
338
324
339
// TODO: workaround to add internal setter, we should remove this once we add lazy initialization for collection type properties
325
- private void AddInternalSetterForFlattenTypeCollectionProperty ( PropertyProvider internalProperty , PropertyProvider innerProperty , PropertyProvider flattenedProperty , ModelProvider modelProvider )
340
+ private void CollectFlattenTypeCollectionProperty ( PropertyProvider internalProperty , PropertyProvider innerProperty , ModelProvider modelProvider )
326
341
{
327
342
if ( innerProperty . Type . IsCollection )
328
343
{
329
344
if ( _collectionTypeProperties . TryGetValue ( modelProvider , out var value ) )
330
345
{
331
- if ( value . TryGetValue ( internalProperty , out var properties ) )
332
- {
333
- properties . Add ( ( flattenedProperty , innerProperty ) ) ;
334
- }
335
- else
336
- {
337
- value . Add ( internalProperty , [ ( flattenedProperty , innerProperty ) ] ) ;
338
- }
346
+ value . Add ( internalProperty ) ;
339
347
}
340
348
else
341
349
{
342
- var dict = new Dictionary < PropertyProvider , List < ( PropertyProvider FlattenedProperty , PropertyProvider InnerProperty ) > > ( ) ;
343
- dict . Add ( internalProperty , [ ( flattenedProperty , innerProperty ) ] ) ;
344
- _collectionTypeProperties . Add ( modelProvider , dict ) ;
350
+ var set = new HashSet < PropertyProvider > ( ) ;
351
+ set . Add ( internalProperty ) ;
352
+ _collectionTypeProperties . Add ( modelProvider , set ) ;
345
353
}
346
- innerProperty . Update ( body : new AutoPropertyBody ( true , MethodSignatureModifiers . Internal ) ) ;
347
354
}
348
355
}
349
356
0 commit comments