5 using System.Runtime.CompilerServices;
7 using Mono.Cecil.Rocks;
8 using Mono.Collections.Generic;
10 namespace SiliconStudio.AssemblyProcessor
17 private AssemblyDefinition assembly;
19 private AssemblyDefinition asyncBridgeAssembly;
23 this.assembly = context.Assembly;
24 asyncBridgeAssembly = context.AssemblyResolver.Resolve(
"AsyncBridge");
26 assembly.MainModule.AssemblyReferences.Add(asyncBridgeAssembly.Name);
28 foreach (var type
in assembly.MainModule.Types)
36 private TypeReference ProcessTypeReference(TypeReference type, IGenericParameterProvider owner)
42 if (type is ByReferenceType)
44 var elementType = ProcessTypeReference(type.GetElementType(), owner);
45 if (elementType != type.GetElementType())
46 type =
new ByReferenceType(elementType);
51 if (type is GenericParameter)
53 var genericParameter = (GenericParameter)type;
54 if ((genericParameter.MetadataType == MetadataType.MVar
55 || genericParameter.MetadataType == MetadataType.Var) && genericParameter.Owner is MethodReference)
57 if (genericParameter.Owner != null && owner != null)
59 return owner.GenericParameters.Concat(genericParameter.Owner.GenericParameters).First(x => x.Name == type.Name);
66 var asyncBridgeType = asyncBridgeAssembly.MainModule.GetTypeResolved(type.Namespace, type.Name);
67 if (asyncBridgeType == null)
71 var genericInstanceType = type as GenericInstanceType;
72 if (genericInstanceType != null)
74 type = genericInstanceType.ElementType;
77 var newType = assembly.MainModule.Import(
new TypeReference(type.Namespace, type.Name, asyncBridgeAssembly.MainModule, asyncBridgeAssembly.Name, type.IsValueType));
79 for (
int i = 0; i < type.GenericParameters.Count; ++i)
81 newType.GenericParameters.Add(
new GenericParameter(type.GenericParameters[i].Name, newType));
82 foreach (var constraint
in type.GenericParameters[i].Constraints)
83 newType.GenericParameters[i].Constraints.Add(ProcessTypeReference(constraint, newType));
86 if (genericInstanceType != null)
88 var newGenericType =
new GenericInstanceType(newType);
89 foreach (var genericArgument
in genericInstanceType.GenericArguments)
91 newGenericType.GenericArguments.Add(ProcessTypeReference(genericArgument, newGenericType));
93 newType = newGenericType;
99 private FieldReference ProcessFieldReference(FieldReference field)
104 field.FieldType = ProcessTypeReference(field.FieldType, field.DeclaringType);
108 private MethodReference ProcessMethodReference(MethodReference method)
113 var declaringType = ProcessTypeReference(method.DeclaringType, null);
114 if (declaringType == method.DeclaringType)
119 var genericInstanceMethod = method as GenericInstanceMethod;
120 if (genericInstanceMethod != null)
122 method = genericInstanceMethod.ElementMethod;
125 var newMethod =
new MethodReference(method.Name, assembly.MainModule.Import(typeof(
void)), declaringType);
126 newMethod.HasThis = method.HasThis;
127 newMethod.ExplicitThis = method.ExplicitThis;
128 newMethod.CallingConvention = method.CallingConvention;
129 newMethod.MethodReturnType = method.MethodReturnType;
130 newMethod.ReturnType = ProcessTypeReference(method.ReturnType, newMethod);
132 for (
int i = 0; i < method.GenericParameters.Count; ++i)
134 newMethod.GenericParameters.Add(
new GenericParameter(method.GenericParameters[i].Name, newMethod));
135 foreach (var constraint
in method.GenericParameters[i].Constraints)
136 newMethod.GenericParameters[i].Constraints.Add(ProcessTypeReference(constraint, newMethod));
139 for (
int i = 0; i < method.Parameters.Count; ++i)
141 var parameterDefinition =
new ParameterDefinition(method.Parameters[i].Name, method.Parameters[i].Attributes, ProcessTypeReference(method.Parameters[i].ParameterType, newMethod));
142 newMethod.Parameters.Add(parameterDefinition);
145 if (genericInstanceMethod != null)
147 var newGenericMethod =
new GenericInstanceMethod(newMethod);
148 foreach (var genericArgument
in genericInstanceMethod.GenericArguments)
150 newGenericMethod.GenericArguments.Add(ProcessTypeReference(genericArgument, newMethod));
152 newMethod = newGenericMethod;
158 private void ProcessType(TypeDefinition type)
160 foreach (var nestedType
in type.NestedTypes)
162 ProcessType(nestedType);
165 type.BaseType = ProcessTypeReference(type.BaseType, null);
167 for (
int i = 0; i < type.Interfaces.Count; ++i)
169 type.Interfaces[i] = ProcessTypeReference(type.Interfaces[i], null);
172 foreach (var field
in type.Fields)
174 field.FieldType = ProcessTypeReference(field.FieldType, null);
177 foreach (var property
in type.Properties)
179 property.PropertyType = ProcessTypeReference(property.PropertyType, null);
182 foreach (var method
in type.Methods)
184 ProcessMethod(method);
187 foreach (var attribute
in type.CustomAttributes)
189 attribute.Constructor = ProcessMethodReference(attribute.Constructor);
193 private void ProcessMethod(MethodDefinition method)
195 for (
int i = 0; i < method.Overrides.Count; ++i)
197 method.Overrides[i] = ProcessMethodReference(method.Overrides[i]);
200 foreach (var parameter
in method.Parameters)
202 parameter.ParameterType = ProcessTypeReference(parameter.ParameterType, null);
205 foreach (var attribute
in method.CustomAttributes)
207 attribute.Constructor = ProcessMethodReference(attribute.Constructor);
210 var methodBody = method.Body;
212 if (methodBody == null)
215 foreach (var variable
in methodBody.Variables)
217 variable.VariableType = ProcessTypeReference(variable.VariableType, null);
220 foreach (var instruction
in methodBody.Instructions)
222 if (instruction.Operand == null)
225 if (instruction.Operand is TypeReference)
226 instruction.Operand = ProcessTypeReference((TypeReference)instruction.Operand, null);
227 else if (instruction.Operand is MethodReference)
228 instruction.Operand = ProcessMethodReference((MethodReference)instruction.Operand);
229 else if (instruction.Operand is FieldReference)
230 instruction.Operand = ProcessFieldReference((FieldReference)instruction.Operand);
Makes the assembly use AsyncBridge instead of mscorlib for async.
bool Process(AssemblyProcessorContext context)