private static IEnumerable <IType> GetAllRequiredTypesForMethod( IMethod method, ReadingTypesContext readingTypesContext) { DicoverGenericSpecializedTypesAndAdditionalTypes( method.ReturnType, readingTypesContext); foreach (var param in method.GetParameters()) { DicoverGenericSpecializedTypesAndAdditionalTypes( param.ParameterType, readingTypesContext); } if (method.DeclaringType.IsInterface) { yield break; } var methodWithCustomBodyOrDefault = MethodBodyBank.GetMethodWithCustomBodyOrDefault(method, _codeWriter); var methodBody = methodWithCustomBodyOrDefault.GetMethodBody(MetadataGenericContext.DiscoverFrom(method)); if (methodBody != null) { foreach (var localVar in methodBody.LocalVariables) { DicoverGenericSpecializedTypesAndAdditionalTypes( localVar.LocalType, readingTypesContext); if (localVar.LocalType.IsStructureType() && !localVar.LocalType.IsPointer && !localVar.LocalType.IsByRef) { yield return(localVar.LocalType); } } var usedStructTypes = new NamespaceContainer <IType>(); methodWithCustomBodyOrDefault.DiscoverRequiredTypesAndMethodsInMethodBody( readingTypesContext.GenericTypeSpecializations, readingTypesContext.GenericMethodSpecializations, usedStructTypes, readingTypesContext.AdditionalTypesToProcess, new Queue <IMethod>()); foreach (var usedStructType in usedStructTypes) { yield return(usedStructType); } } }
/// <summary> /// </summary> /// <param name="ilReader"> /// </param> /// <param name="codeWriter"> /// </param> /// <param name="type"> /// </param> /// <param name="typeDefinition"> /// </param> /// <param name="genericMethodSpecializatons"> /// </param> /// <param name="mode"> /// </param> /// <param name="processGenericMethodsOnly"> /// </param> private static void ConvertIType( IlReader ilReader, ICodeWriter codeWriter, IType type, IEnumerable <IMethod> genericMethodSpecializatons, ConvertingMode mode, bool processGenericMethodsOnly = false) { if (VerboseOutput) { Trace.WriteLine(string.Format("Converting {0}, Mode: {1}", type, mode)); } var typeDefinition = type.IsGenericType ? type.GetTypeDefinition() : null; var typeSpecialization = type.IsGenericType && !type.IsGenericTypeDefinition ? type : null; var genericTypeContext = typeDefinition != null || typeSpecialization != null ? MetadataGenericContext.Create(typeDefinition, typeSpecialization) : null; if (mode == ConvertingMode.Declaration) { if (!codeWriter.IsProcessed(type)) { WriteTypeDefinition(codeWriter, type, genericTypeContext); } codeWriter.WritePostDeclarationsAndInternalDefinitions(type); codeWriter.WriteBeforeConstructors(); } if (mode == ConvertingMode.Definition) { codeWriter.DisableWrite(true); if (!processGenericMethodsOnly) { // pre process step to get all used undefined structures foreach (var ctor in IlReader.Constructors(type, codeWriter)) { codeWriter.WriteConstructorStart(ctor, genericTypeContext); foreach (var ilCode in ilReader.OpCodes(type.IsGenericType ? ctor.GetMethodDefinition() : ctor, genericTypeContext)) { codeWriter.Write(ilCode); } codeWriter.WriteConstructorEnd(ctor, genericTypeContext); } } codeWriter.DisableWrite(false); // Actual Write codeWriter.WriteRequiredTypesForBody(); codeWriter.WriteStoredText(); } if (mode == ConvertingMode.Declaration) { codeWriter.WriteAfterConstructors(); codeWriter.WriteBeforeMethods(); } if (mode == ConvertingMode.Definition) { codeWriter.DisableWrite(true); // pre process step to get all used undefined structures foreach ( var method in IlReader.Methods(type, codeWriter, true).Select(m => MethodBodyBank.GetMethodWithCustomBodyOrDefault(m, codeWriter))) { if (!method.IsGenericMethodDefinition && !processGenericMethodsOnly) { var genericMethodContext = method.IsGenericMethod ? MetadataGenericContext.Create(typeDefinition, typeSpecialization, method.GetMethodDefinition(), method) : genericTypeContext; codeWriter.WriteMethodStart(method, genericMethodContext); foreach (var ilCode in ilReader.OpCodes(type.IsGenericType ? method.GetMethodDefinition() : method, genericMethodContext)) { codeWriter.Write(ilCode); } codeWriter.WriteMethodEnd(method, genericMethodContext); } if (method.IsGenericMethodDefinition || method.IsGenericMethod) { // write all specializations of a method if (genericMethodSpecializatons != null) { var methodDefinition = method.GetMethodDefinition(); foreach ( var methodSpec in genericMethodSpecializatons.Where( methodSpec => methodSpec.IsMatchingGeneric(methodDefinition) && (!methodSpec.Equals(method) || processGenericMethodsOnly))) { var genericMethodContext = MetadataGenericContext.Create(typeDefinition, typeSpecialization, method, methodSpec); codeWriter.WriteMethodStart(methodSpec, genericMethodContext); foreach (var ilCode in ilReader.OpCodes(methodDefinition ?? method, genericMethodContext)) { codeWriter.Write(ilCode); } codeWriter.WriteMethodEnd(methodSpec, genericMethodContext); } } } } codeWriter.DisableWrite(false); // Actual Write codeWriter.WriteRequiredTypesForBody(); codeWriter.WriteStoredText(); } if (mode == ConvertingMode.Declaration) { codeWriter.WriteAfterMethods(); codeWriter.WriteTypeEnd(type); } }