5 using System.Collections.Generic;
8 using System.Reflection;
11 using SiliconStudio.Core.Serialization;
12 using SiliconStudio.Core.Storage;
14 namespace SiliconStudio.AssemblyProcessor
19 private static readonly MethodInfo containsGenericParameterGetMethod = typeof(MemberReference).GetProperty(
"ContainsGenericParameter", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetMethod;
23 foreach (var type
in assembly.MainModule.Types)
26 foreach (var nestedType
in type.NestedTypes)
28 yield
return nestedType;
33 public static TypeReference
MakeGenericType(
this TypeReference
self, params TypeReference[] arguments)
35 if (
self.GenericParameters.Count != arguments.Length)
36 throw new ArgumentException();
38 var instance =
new GenericInstanceType(
self);
39 foreach (var argument
in arguments)
40 instance.GenericArguments.Add(argument);
45 public static FieldReference
MakeGeneric(
this FieldReference
self, params TypeReference[] arguments)
47 return new FieldReference(
self.Name,
self.FieldType,
self.DeclaringType.MakeGenericType(arguments));
50 public static MethodReference
MakeGeneric(
this MethodReference
self, params TypeReference[] arguments)
52 var reference =
new MethodReference(
self.Name,
self.ReturnType,
self.DeclaringType.MakeGenericType(arguments))
54 HasThis = self.HasThis,
55 ExplicitThis = self.ExplicitThis,
56 CallingConvention = self.CallingConvention,
59 foreach (var parameter
in self.Parameters)
60 reference.Parameters.Add(
new ParameterDefinition(parameter.ParameterType));
62 foreach (var generic_parameter
in self.GenericParameters)
63 reference.GenericParameters.Add(
new GenericParameter(generic_parameter.Name, reference));
68 public static MethodReference
MakeGenericMethod(
this MethodReference
self, params TypeReference[] arguments)
70 var method =
new GenericInstanceMethod(
self);
71 foreach(var argument
in arguments)
72 method.GenericArguments.Add(argument);
76 public static TypeDefinition
GetTypeResolved(
this ModuleDefinition moduleDefinition,
string typeName)
78 foreach (var exportedType
in moduleDefinition.ExportedTypes)
80 if (exportedType.FullName == typeName)
82 var typeDefinition = exportedType.Resolve();
83 return typeDefinition;
87 return moduleDefinition.GetType(typeName);
90 public static TypeDefinition
GetTypeResolved(
this ModuleDefinition moduleDefinition,
string @
namespace,
string typeName)
92 foreach (var exportedType
in moduleDefinition.ExportedTypes)
94 if (exportedType.Namespace == @
namespace && exportedType.Name == typeName)
96 var typeDefinition = exportedType.Resolve();
97 return typeDefinition;
101 return moduleDefinition.GetType(@
namespace, typeName);
112 AssemblyDefinition mscorlibAssembly = null;
114 foreach (var assemblyNameReference
in assembly.MainModule.AssemblyReferences)
116 if (assemblyNameReference.Name.ToLower() ==
"mscorlib")
118 mscorlibAssembly = assembly.MainModule.AssemblyResolver.Resolve(assemblyNameReference);
122 return mscorlibAssembly;
132 || (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable(
"PROCESSOR_ARCHITEW6432"))))
134 return Environment.GetEnvironmentVariable(
"ProgramFiles(x86)");
137 return Environment.GetEnvironmentVariable(
"ProgramFiles");
142 if (elementType != type.ElementType || genericArguments != type.GenericArguments)
144 var result =
new GenericInstanceType(elementType);
145 foreach (var genericArgument
in genericArguments)
146 result.GenericArguments.Add(genericArgument);
147 if (type.HasGenericParameters)
148 SetGenericParameters(result, type.GenericParameters);
154 public static ArrayType
ChangeArrayType(
this ArrayType type, TypeReference elementType,
int rank)
156 if (elementType != type.ElementType || rank != type.Rank)
158 var result =
new ArrayType(elementType, rank);
159 if (type.HasGenericParameters)
160 SetGenericParameters(result, type.GenericParameters);
168 if (type.GenericParameters == genericParameters)
171 TypeReference result;
172 var arrayType = type as ArrayType;
173 if (arrayType != null)
175 result =
new ArrayType(arrayType.ElementType, arrayType.Rank);
179 var genericInstanceType = type as GenericInstanceType;
180 if (genericInstanceType != null)
182 result =
new GenericInstanceType(genericInstanceType.ElementType);
184 else if (type.GetType() == typeof(TypeReference).GetType())
186 result =
new TypeReference(type.Namespace, type.Name, type.Module, type.Scope, type.IsValueType);
190 throw new NotSupportedException();
194 SetGenericParameters(result, genericParameters);
201 foreach (var genericParameter
in genericParameters)
202 result.GenericParameters.Add(genericParameter);
207 var genericInstanceType = type as GenericInstanceType;
208 if (!type.HasGenericParameters && genericInstanceType == null)
211 var result =
new StringBuilder();
214 if (genericInstanceType != null)
219 foreach (var genericArgument
in genericInstanceType.GenericArguments)
225 result.Append(ConvertCSharp(genericArgument, empty));
230 return result.ToString();
233 if (type.HasGenericParameters)
238 foreach (var genericParameter
in type.GenericParameters)
244 result.Append(ConvertCSharp(genericParameter, empty));
249 return result.ToString();
252 return result.ToString();
257 var typeName = type.ConvertCSharp(
false);
258 var typeId = ObjectId.FromBytes(Encoding.UTF8.GetBytes(typeName));
260 var typeIdHash = (uint*)&typeId;
261 return string.Format(
"new {0}(0x{1:x8}, 0x{2:x8}, 0x{3:x8}, 0x{4:x8})", typeof(
ObjectId).FullName, typeIdHash[0], typeIdHash[1], typeIdHash[2], typeIdHash[3]);
270 public static string ConvertCSharp(
this TypeReference type,
bool empty =
false)
273 var arrayType = type as ArrayType;
274 if (arrayType != null)
276 return ConvertCSharp(arrayType.ElementType, empty) +
"[]";
280 var typeName = type.GetElementType().FullName;
281 var genericSeparatorIndex = typeName.LastIndexOf(
'`');
282 if (genericSeparatorIndex != -1)
283 typeName = typeName.Substring(0, genericSeparatorIndex);
286 typeName = typeName.Replace(
'/',
'.');
289 var genericInstanceType = type as GenericInstanceType;
290 if (genericInstanceType != null)
292 var result =
new StringBuilder();
295 result.Append(typeName);
299 foreach (var genericArgument
in genericInstanceType.GenericArguments)
305 result.Append(ConvertCSharp(genericArgument, empty));
310 return result.ToString();
313 if (type.HasGenericParameters)
315 var result =
new StringBuilder();
318 result.Append(typeName);
322 foreach (var genericParameter
in type.GenericParameters)
328 result.Append(ConvertCSharp(genericParameter, empty));
333 return result.ToString();
345 public static TypeReference
GenerateTypeCecil(
this Type type, BaseAssemblyResolver assemblyResolver)
347 var assemblyDefinition = assemblyResolver.Resolve(type.Assembly.FullName);
348 TypeReference typeReference;
352 var declaringType = GenerateTypeCecil(type.DeclaringType, assemblyResolver);
353 typeReference = declaringType.Resolve().NestedTypes.FirstOrDefault(x => x.Name == type.Name);
355 else if (type.IsArray)
357 var elementType = GenerateTypeCecil(type.GetElementType(), assemblyResolver);
358 typeReference =
new ArrayType(elementType, type.GetArrayRank());
362 typeReference = assemblyDefinition.MainModule.GetTypeResolved(type.IsGenericType ? type.GetGenericTypeDefinition().FullName : type.FullName);
365 if (typeReference == null)
366 throw new InvalidOperationException(
"Could not resolve cecil type.");
368 if (type.IsGenericType)
370 var genericInstanceType =
new GenericInstanceType(typeReference);
371 foreach (var argType
in type.GetGenericArguments())
373 TypeReference argTypeReference;
374 if (argType.IsGenericParameter)
376 argTypeReference =
new GenericParameter(argType.Name, typeReference);
380 argTypeReference = GenerateTypeCecil(argType, assemblyResolver);
382 genericInstanceType.GenericArguments.Add(argTypeReference);
385 typeReference = genericInstanceType;
388 return typeReference;
393 return (
bool)containsGenericParameterGetMethod.Invoke(memberReference, null);
403 var result =
new StringBuilder(256);
404 ConvertAssemblyQualifiedName(type, result);
405 return result.ToString();
408 private static void ConvertAssemblyQualifiedName(
this TypeReference type, StringBuilder result)
412 var arrayType = type as ArrayType;
413 if (arrayType != null)
416 type = arrayType.ElementType;
420 start = result.Length;
421 result.Append(type.GetElementType().FullName);
425 result = result.Replace(
'/',
'+', start, end);
428 var genericInstanceType = type as GenericInstanceType;
429 if (genericInstanceType != null)
433 bool containsGenericParameter =
false;
434 foreach (var genericArgument
in genericInstanceType.GenericArguments)
436 if (genericArgument.IsGenericParameter)
437 containsGenericParameter =
true;
440 if (!containsGenericParameter)
446 foreach (var genericArgument
in genericInstanceType.GenericArguments)
452 result.Append(ConvertAssemblyQualifiedName(genericArgument));
461 if (arrayType != null)
464 if (arrayType.Rank > 1)
465 result.Append(
',', arrayType.Rank - 1);
470 start = result.Length;
471 result.Append(type.Module.Assembly.FullName);
474 #if SILICONSTUDIO_PLATFORM_MONO_MOBILE
476 const string oldTypeEnding =
"2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e";
477 const string newTypeEnding =
"4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
478 result = result.Replace(oldTypeEnding, newTypeEnding, start, end);
static string ConvertCSharp(this TypeReference type, bool empty=false)
Generates type name valid to use from C# source file.
static MethodReference MakeGenericMethod(this MethodReference self, params TypeReference[] arguments)
static AssemblyDefinition FindCorlibAssembly(AssemblyDefinition assembly)
Finds the corlib assembly.
static IEnumerable< TypeDefinition > EnumerateTypes(this AssemblyDefinition assembly)
static TypeDefinition GetTypeResolved(this ModuleDefinition moduleDefinition, string typeName)
static TypeReference GenerateTypeCecil(this Type type, BaseAssemblyResolver assemblyResolver)
Generates the Mono.Cecil TypeReference from its .NET Type counterpart.
static GenericInstanceType ChangeGenericInstanceType(this GenericInstanceType type, TypeReference elementType, IEnumerable< TypeReference > genericArguments)
static string ProgramFilesx86()
Get Program Files x86
static MethodReference MakeGeneric(this MethodReference self, params TypeReference[] arguments)
static TypeDefinition GetTypeResolved(this ModuleDefinition moduleDefinition, string @namespace, string typeName)
static string ConvertAssemblyQualifiedName(this TypeReference type)
Generates type name similar to Type.AssemblyQualifiedName.
static TypeReference MakeGenericType(this TypeReference self, params TypeReference[] arguments)
static FieldReference MakeGeneric(this FieldReference self, params TypeReference[] arguments)
static unsafe string ConvertTypeId(this TypeReference type)
A hash to uniquely identify data.
static ArrayType ChangeArrayType(this ArrayType type, TypeReference elementType, int rank)
static bool ContainsGenericParameter(this MemberReference memberReference)
static TypeReference ChangeGenericParameters(this TypeReference type, IEnumerable< GenericParameter > genericParameters)
static string GenerateGenerics(this TypeReference type, bool empty=false)