@@ -28,104 +28,106 @@ public override bool WillProcess(ICompiledAssembly compiledAssembly)
28
28
29
29
public override ILPostProcessResult Process ( ICompiledAssembly compiledAssembly )
30
30
{
31
- var logger = new ILPostProcessorLogger ( new List < DiagnosticMessage > ( ) ) ;
32
31
using var resolver = new PostProcessorAssemblyResolver ( compiledAssembly . References ) ;
33
32
using var assembly = compiledAssembly . LoadAssembly ( resolver ) ;
34
- var referenceAssemblies = compiledAssembly . LoadLibraryAssemblies ( resolver ) . ToArray ( ) ;
35
- try
33
+ var logger = assembly . CreateLogger ( ) ;
34
+ logger . Info ( $ "process GenericSerializeReference on { assembly . Name . Name } ({ string . Join ( "," , compiledAssembly . References . Where ( r => r . StartsWith ( "Library" ) ) ) } )") ;
35
+ var modified = Process ( compiledAssembly , assembly , resolver , logger ) ;
36
+ if ( ! modified ) return new ILPostProcessResult ( null , logger . Messages ) ;
37
+
38
+ var pe = new MemoryStream ( ) ;
39
+ var pdb = new MemoryStream ( ) ;
40
+ var writerParameters = new WriterParameters
36
41
{
37
- var loggerAttributes = assembly . GetAttributesOf < GenericSerializeReferenceLoggerAttribute > ( ) ;
38
- if ( loggerAttributes . Any ( ) ) logger . LogLevel = ( LogLevel ) loggerAttributes . First ( ) . ConstructorArguments [ 0 ] . Value ;
39
- logger . Info ( $ "process GenericSerializeReference on { assembly . Name . Name } ({ string . Join ( "," , referenceAssemblies . Select ( r => r . Name . Name ) ) } )") ;
40
- var allTypes = referenceAssemblies . Append ( assembly )
41
- . Where ( asm => ! asm . Name . Name . StartsWith ( "Unity." )
42
- && ! asm . Name . Name . StartsWith ( "UnityEditor." )
43
- && ! asm . Name . Name . StartsWith ( "UnityEngine." )
44
- )
45
- . SelectMany ( asm => asm . MainModule . GetAllTypes ( ) )
46
- ;
47
- logger . Debug ( $ "all types: { string . Join ( ", " , allTypes . Select ( t => t . Name ) ) } ") ;
48
- var typeTree = new TypeTree ( allTypes ) ;
49
- logger . Debug ( $ "tree: { typeTree } ") ;
50
- var modified = Process ( assembly . MainModule , typeTree , logger ) ;
51
- if ( ! modified ) return new ILPostProcessResult ( null , logger . Messages ) ;
42
+ SymbolWriterProvider = new PortablePdbWriterProvider ( ) , SymbolStream = pdb , WriteSymbols = true
43
+ } ;
44
+ assembly . Write ( pe , writerParameters ) ;
45
+ // assembly.Write();
46
+ var inMemoryAssembly = new InMemoryAssembly ( pe . ToArray ( ) , pdb . ToArray ( ) ) ;
47
+ return new ILPostProcessResult ( inMemoryAssembly , logger . Messages ) ;
48
+ }
52
49
53
- var pe = new MemoryStream ( ) ;
54
- var pdb = new MemoryStream ( ) ;
55
- var writerParameters = new WriterParameters
56
- {
57
- SymbolWriterProvider = new PortablePdbWriterProvider ( ) , SymbolStream = pdb , WriteSymbols = true
58
- } ;
59
- assembly . Write ( pe , writerParameters ) ;
60
- // assembly.Write();
61
- var inMemoryAssembly = new InMemoryAssembly ( pe . ToArray ( ) , pdb . ToArray ( ) ) ;
62
- return new ILPostProcessResult ( inMemoryAssembly , logger . Messages ) ;
50
+ private bool Process ( ICompiledAssembly compiledAssembly , AssemblyDefinition assembly , PostProcessorAssemblyResolver resolver , ILPostProcessorLogger logger )
51
+ {
52
+ var module = assembly . MainModule ;
53
+ IReadOnlyList < AssemblyDefinition > referenceAssemblies = Array . Empty < AssemblyDefinition > ( ) ;
54
+ TypeTree typeTree = null ;
55
+
56
+ try
57
+ {
58
+ return ProcessProperties ( ) ;
63
59
}
64
60
finally
65
61
{
66
- foreach ( var reference in referenceAssemblies ) reference . Dispose ( ) ;
62
+ foreach ( var @ref in referenceAssemblies ) @ref . Dispose ( ) ;
67
63
}
68
- }
69
64
70
- private bool Process ( ModuleDefinition module , TypeTree typeTree , ILPostProcessorLogger logger )
71
- {
72
- var modified = false ;
73
- foreach ( var ( type , property , attribute ) in
74
- from type in module . GetAllTypes ( )
75
- where type . IsClass && ! type . IsAbstract
76
- from property in type . Properties . ToArray ( ) // able to change `Properties` during looping
77
- from attribute in property . GetAttributesOf < GenericSerializeReferenceAttribute > ( )
78
- select ( type , property , attribute )
79
- )
65
+ bool ProcessProperties ( )
80
66
{
81
- if ( property . GetMethod == null )
67
+ var modified = false ;
68
+ foreach ( var ( type , property , attribute ) in
69
+ from type in module . GetAllTypes ( )
70
+ where type . IsClass && ! type . IsAbstract
71
+ from property in type . Properties . ToArray ( ) // able to change `Properties` during looping
72
+ from attribute in property . GetAttributesOf < GenericSerializeReferenceAttribute > ( )
73
+ select ( type , property , attribute )
74
+ )
82
75
{
83
- logger . Warning ( $ "Cannot process on property { property } without getter") ;
84
- continue ;
85
- }
76
+ if ( property . GetMethod == null )
77
+ {
78
+ logger . Warning ( $ "Cannot process on property { property } without getter") ;
79
+ continue ;
80
+ }
86
81
87
- if ( ! property . PropertyType . IsGenericInstance )
88
- {
89
- logger . Warning ( $ "Cannot process on property { property } with non-generic type { property . PropertyType . Name } ") ;
90
- continue ;
91
- }
82
+ if ( ! property . PropertyType . IsGenericInstance )
83
+ {
84
+ logger . Warning ( $ "Cannot process on property { property } with non-generic type { property . PropertyType . Name } ") ;
85
+ continue ;
86
+ }
92
87
93
- TypeReference baseInterface ;
94
- var mode = ( GenerateMode ) attribute . ConstructorArguments [ 1 ] . Value ;
95
- if ( mode == GenerateMode . Embed )
96
- {
97
- var wrapperName = $ "<{ property . Name } >__generic_serialize_reference";
98
- var wrapper = property . DeclaringType . CreateNestedStaticPrivateClass ( wrapperName ) ;
99
- baseInterface = CreateInterface ( wrapper ) ;
100
- CreateDerivedClasses ( property , wrapper , baseInterface ) ;
101
- }
102
- else
103
- {
104
- baseInterface = module . ImportReference ( typeof ( IBase ) ) ;
105
- }
88
+ TypeReference baseInterface ;
89
+ var mode = ( GenerateMode ) attribute . ConstructorArguments [ 1 ] . Value ;
90
+ if ( mode == GenerateMode . Embed )
91
+ {
92
+ var wrapperName = $ "<{ property . Name } >__generic_serialize_reference";
93
+ var wrapper = property . DeclaringType . CreateNestedStaticPrivateClass ( wrapperName ) ;
94
+ baseInterface = CreateInterface ( wrapper ) ;
95
+ CreateDerivedClasses ( property , wrapper , baseInterface ) ;
96
+ }
97
+ else
98
+ {
99
+ baseInterface = module . ImportReference ( typeof ( IBase ) ) ;
100
+ }
106
101
107
- logger . Info ( $ "generate nested class with interface { baseInterface . FullName } ") ;
108
- var fieldNamePrefix = ( string ) attribute . ConstructorArguments [ 0 ] . Value ;
109
- GenerateField ( module , property , baseInterface , fieldNamePrefix ) ;
102
+ logger . Info ( $ "generate nested class with interface { baseInterface . FullName } ") ;
103
+ var fieldNamePrefix = ( string ) attribute . ConstructorArguments [ 0 ] . Value ;
104
+ GenerateField ( module , property , baseInterface , fieldNamePrefix ) ;
110
105
111
- modified = true ;
106
+ modified = true ;
107
+ }
108
+ return modified ;
112
109
}
113
- return modified ;
114
110
115
- TypeDefinition CreateInterface ( TypeDefinition wrapper , string interfaceName = "IBase" )
111
+ void CreateTypeTree ( )
116
112
{
117
- // .class interface nested public abstract auto ansi
118
- var interfaceAttributes = TypeAttributes . Class |
119
- TypeAttributes . Interface |
120
- TypeAttributes . NestedPublic |
121
- TypeAttributes . Abstract ;
122
- var baseInterface = new TypeDefinition ( "" , interfaceName , interfaceAttributes ) ;
123
- wrapper . NestedTypes . Add ( baseInterface ) ;
124
- return baseInterface ;
113
+ if ( typeTree != null ) return ;
114
+
115
+ referenceAssemblies = compiledAssembly . LoadLibraryAssemblies ( resolver ) . ToArray ( ) ;
116
+ var allTypes = referenceAssemblies . Append ( assembly )
117
+ . Where ( asm => ! asm . Name . Name . StartsWith ( "Unity." )
118
+ && ! asm . Name . Name . StartsWith ( "UnityEditor." )
119
+ && ! asm . Name . Name . StartsWith ( "UnityEngine." )
120
+ )
121
+ . SelectMany ( asm => asm . MainModule . GetAllTypes ( ) )
122
+ ;
123
+ logger . Debug ( $ "all types: { string . Join ( ", " , allTypes . Select ( t => t . Name ) ) } ") ;
124
+ typeTree = new TypeTree ( allTypes ) ;
125
+ logger . Debug ( $ "tree: { typeTree } ") ;
125
126
}
126
127
127
128
void CreateDerivedClasses ( PropertyDefinition property , TypeDefinition wrapper , TypeReference baseInterface )
128
129
{
130
+ if ( typeTree == null ) CreateTypeTree ( ) ;
129
131
logger . Debug ( $ "get derived { property . PropertyType . Module } { property . PropertyType } { property . PropertyType . Resolve ( ) } ") ;
130
132
foreach ( var derived in typeTree . GetOrCreateAllDerivedReference ( property . PropertyType ) )
131
133
{
@@ -151,7 +153,19 @@ void CreateDerivedClasses(PropertyDefinition property, TypeDefinition wrapper, T
151
153
}
152
154
}
153
155
154
- internal static void GenerateField (
156
+ private TypeDefinition CreateInterface ( TypeDefinition wrapper , string interfaceName = "IBase" )
157
+ {
158
+ // .class interface nested public abstract auto ansi
159
+ var interfaceAttributes = TypeAttributes . Class |
160
+ TypeAttributes . Interface |
161
+ TypeAttributes . NestedPublic |
162
+ TypeAttributes . Abstract ;
163
+ var baseInterface = new TypeDefinition ( "" , interfaceName , interfaceAttributes ) ;
164
+ wrapper . NestedTypes . Add ( baseInterface ) ;
165
+ return baseInterface ;
166
+ }
167
+
168
+ private static void GenerateField (
155
169
ModuleDefinition module ,
156
170
PropertyDefinition property ,
157
171
TypeReference fieldType ,
@@ -162,7 +176,7 @@ internal static void GenerateField(
162
176
InjectSetter ( property , serializedField ) ;
163
177
}
164
178
165
- internal static FieldDefinition CreateSerializeReferenceField (
179
+ private static FieldDefinition CreateSerializeReferenceField (
166
180
ModuleDefinition module ,
167
181
PropertyDefinition property ,
168
182
TypeReference @interface ,
@@ -183,7 +197,7 @@ internal static FieldDefinition CreateSerializeReferenceField(
183
197
return serializedField ;
184
198
}
185
199
186
- internal static void InjectGetter ( PropertyDefinition property , FieldDefinition serializedField )
200
+ private static void InjectGetter ( PropertyDefinition property , FieldDefinition serializedField )
187
201
{
188
202
// --------add--------
189
203
// IL_0000: ldarg.0 // this
@@ -206,7 +220,7 @@ internal static void InjectGetter(PropertyDefinition property, FieldDefinition s
206
220
instructions . Insert ( 4 , Instruction . Create ( OpCodes . Pop ) ) ;
207
221
}
208
222
209
- internal static void InjectSetter ( PropertyDefinition property , FieldDefinition serializedField )
223
+ private static void InjectSetter ( PropertyDefinition property , FieldDefinition serializedField )
210
224
{
211
225
//IL_0000: ldarg.0 // this
212
226
//IL_0001: ldarg.1 // 'value'
0 commit comments