/// <summary> /// </summary> /// <param name="method"> /// </param> /// <param name="genericTypeSpecializations"> /// </param> /// <param name="genericMethodSpecializations"> /// </param> /// <param name="structTypes"> /// </param> /// <param name="stackCall"> /// </param> public static void DiscoverRequiredTypesAndMethodsInMethodBody( this IMethod method, ISet <IType> genericTypeSpecializations, ISet <IMethod> genericMethodSpecializations, ISet <IType> structTypes, ISet <IType> arrayTypes, Queue <IMethod> stackCall) { if (Il2Converter.VerboseOutput) { Debug.WriteLine("Scanning method for types: {0}", method); } // read method body to extract all types var reader = new IlReader(); reader.UsedStructTypes = structTypes; reader.UsedArrayTypes = arrayTypes; reader.UsedGenericSpecialiazedTypes = genericTypeSpecializations; reader.UsedGenericSpecialiazedMethods = genericMethodSpecializations; var genericContext = MetadataGenericContext.DiscoverFrom(method, false); // true foreach (var op in reader.OpCodes(method, genericContext, stackCall)) { } }
/// <summary> /// </summary> /// <param name="method"> /// </param> /// <param name="structTypes"> /// </param> /// <param name="calledMethods"> /// </param> /// <param name="readStaticFields"> /// </param> public static void DiscoverMethod(this IMethod method, ISet <IType> structTypes, ISet <IMethod> calledMethods, ISet <IField> readStaticFields) { // read method body to extract all types var reader = new IlReader(); reader.UsedTypes = structTypes; reader.CalledMethods = calledMethods; reader.UsedStaticFieldsToRead = readStaticFields; var genericContext = MetadataGenericContext.DiscoverFrom(method); foreach (var op in reader.OpCodes(method, genericContext, new Queue <IMethod>())) { } }
/// <summary> /// </summary> /// <param name="method"> /// </param> /// <param name="genericTypeSpecializations"> /// </param> /// <param name="genericMethodSpecializations"> /// </param> /// <param name="requiredTypes"> /// </param> /// <param name="stackCall"> /// </param> public static void DiscoverRequiredTypesAndMethodsInMethodBody( this IMethod method, ISet <IType> genericTypeSpecializations, ISet <IMethod> genericMethodSpecializations, ISet <IType> requiredTypes, Queue <IMethod> stackCall) { // read method body to extract all types var reader = new IlReader(); reader.UsedStructTypes = requiredTypes; reader.UsedGenericSpecialiazedTypes = genericTypeSpecializations; reader.UsedGenericSpecialiazedMethods = genericMethodSpecializations; var genericContext = MetadataGenericContext.DiscoverFrom(method, false); // true foreach (var op in reader.OpCodes(method, genericContext, stackCall)) { } }
/// <summary> /// </summary> /// <param name="ilReader"> /// </param> /// <param name="codeWriter"> /// </param> /// <param name="type"> /// </param> /// <param name="genericDefinition"> /// </param> /// <param name="genericMethodSpecializatons"> /// </param> /// <param name="mode"> /// </param> /// <param name="processGenericMethodsOnly"> /// </param> private static void ConvertIType( IlReader ilReader, ICodeWriter codeWriter, IType type, IType genericDefinition, IEnumerable <IMethod> genericMethodSpecializatons, ConvertingMode mode, bool processGenericMethodsOnly = false) { Debug.WriteLine("Converting {0}, Mode: {1}", type, mode); var typeSpecialization = type.IsGenericType && !type.IsGenericTypeDefinition ? type : null; var genericContext = new MetadataGenericContext(); genericContext.TypeDefinition = genericDefinition; genericContext.TypeSpecialization = typeSpecialization; genericContext.MethodDefinition = null; genericContext.MethodSpecialization = null; if (mode == ConvertingMode.Declaration) { if (!codeWriter.IsProcessed(type)) { WriteTypeDefinition(codeWriter, type, genericContext); } codeWriter.WritePostDeclarations(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)) { IConstructor genericCtor = null; if (type.IsGenericType && !type.IsInterface && !type.IsDelegate) { // find the same constructor in generic class Debug.Assert(genericDefinition != null); genericCtor = IlReader.Constructors(genericDefinition).First(gm => ctor.IsMatchingGeneric(gm)); } genericContext.MethodDefinition = genericCtor; genericContext.MethodSpecialization = null; codeWriter.WriteConstructorStart(ctor, genericContext); foreach (var ilCode in ilReader.OpCodes(genericCtor ?? ctor, genericContext)) { codeWriter.Write(ilCode); } codeWriter.WriteConstructorEnd(ctor, genericContext); } } 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.MethodsOriginal(type).Select(m => MethodBodyBank.GetMethodBodyOrDefault(m, codeWriter))) { IMethod genericMethod = null; if (type.IsGenericType && !type.IsInterface && !type.IsDelegate) { // find the same method in generic class genericMethod = IlReader.MethodsOriginal(genericDefinition).First(gm => method.IsMatchingGeneric(gm.ToSpecialization(genericContext))); } if (!method.IsGenericMethodDefinition && !processGenericMethodsOnly) { genericContext.MethodDefinition = genericMethod; genericContext.MethodSpecialization = genericMethod != null ? method : null; codeWriter.WriteMethodStart(method, genericContext); foreach (var ilCode in ilReader.OpCodes(genericMethod ?? method, genericContext)) { codeWriter.Write(ilCode); } codeWriter.WriteMethodEnd(method, genericContext); } else { // write all specializations of a method if (genericMethodSpecializatons != null) { foreach (var methodSpec in genericMethodSpecializatons) { if (!methodSpec.IsMatchingGeneric(method)) { continue; } genericContext.MethodDefinition = method; genericContext.MethodSpecialization = methodSpec; codeWriter.WriteMethodStart(methodSpec, genericContext); foreach (var ilCode in ilReader.OpCodes(genericMethod ?? method, genericContext)) { codeWriter.Write(ilCode); } codeWriter.WriteMethodEnd(methodSpec, genericContext); } } } } codeWriter.DisableWrite(false); // Actual Write codeWriter.WriteRequiredTypesForBody(); codeWriter.WriteStoredText(); } if (mode == ConvertingMode.Declaration) { codeWriter.WriteAfterMethods(); codeWriter.WriteTypeEnd(type); } }
/// <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); } }