internal static void WriteConstStrings( CodeTextWriter twSource, TranslateContext translateContext) { IExtractContext extractContext = translateContext; var constStrings = extractContext. ExtractConstStrings(). ToArray(); if (constStrings.Length >= 1) { twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// [9-1] Const strings:"); twSource.SplitLine(); foreach (var(symbolName, value) in extractContext.ExtractConstStrings()) { var expr = Utilities.GetCLanguageExpression(value); twSource.WriteLine( "IL2C_CONST_STRING({0}, {1});", symbolName, expr); } twSource.SplitLine(); } }
public static string GetStaticFieldPrototypeString( FieldReference field, bool requireInitializerExpression, IExtractContext extractContext) { var initializer = String.Empty; if (requireInitializerExpression) { if (field.FieldType.IsNumericPrimitive()) { // TODO: numericPrimitive and (literal or readonly static) ? var fieldDefinition = field.Resolve(); Debug.Assert(fieldDefinition.IsStatic); var value = fieldDefinition.HasConstant ? fieldDefinition.Constant : 0; Debug.Assert(value != null); initializer = fieldDefinition.FieldType.IsInt64Type() ? String.Format(" = {0}LL", value) : String.Format(" = {0}", value); } else if (field.FieldType.IsValueType == false) { initializer = " = NULL"; } } return(string.Format( "{0} {1}{2}", extractContext.GetCLanguageTypeName(field.FieldType), field.GetFullMemberName().ManglingSymbolName(), initializer)); }
internal static void WriteDeclaredValues( CodeTextWriter twSource, TranslateContext translateContext) { IExtractContext extractContext = translateContext; var declaredValues = extractContext. ExtractDeclaredValues(). ToArray(); if (declaredValues.Length >= 1) { twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// [12-1] Declared values:"); foreach (var information in extractContext.ExtractDeclaredValues()) { twSource.SplitLine(); foreach (var declaredFields in information.DeclaredFields) { twSource.WriteLine( "// {0}", declaredFields.FriendlyName); } var targetType = (information.HintTypes.Length == 1) ? information.HintTypes[0] : extractContext.MetadataContext.ByteType.MakeArray(); Debug.Assert(targetType.IsArray); var elementType = targetType.ElementType.ResolveToRuntimeType(); var values = Utilities.ResourceDataToSpecificArray(information.ResourceData, elementType); var lhs = targetType.GetCLanguageTypeName(information.SymbolName, true); var expr = Utilities.GetCLanguageExpression(values); twSource.WriteLine( "static const {0} =", lhs); using (var _ = twSource.Shift()) { twSource.WriteLine( "{0};", expr); } } twSource.SplitLine(); } }
public static string GetFunctionTypeString( TypeReference returnType, TypeReference[] parameterTypes, IExtractContext extractContext) { var parametersString = string.Join( ", ", parameterTypes.Select(parameterType => extractContext.GetCLanguageTypeName(parameterType))); var returnTypeName = extractContext.GetCLanguageTypeName(returnType); return(string.Format( "{0} (*)({1})", returnTypeName, (parametersString.Length >= 1) ? parametersString : "void")); }
private static void InternalWriteAssemblyReferences( CodeTextWriter tw, TranslateContext translateContext, IExtractContext extractContext, ITypeInformation declaringType) { foreach (var assembly in extractContext.EnumerateRegisteredTypesByDeclaringType(declaringType). Distinct(). OrderByDependant(declaringType.DeclaringModule.DeclaringAssembly). Select(type => type.DeclaringModule.DeclaringAssembly). Where(assembly => !assembly.Equals(translateContext.Assembly)). Distinct(). OrderBy(assembly => assembly.Name)) { tw.WriteLine("#include <{0}.h>", assembly.Name); } tw.SplitLine(); }
private static VirtualMethodInformation[] GetVirtualMethods( IExtractContext extractContext, TypeReference adjustorThunkTargetType, TypeReference delegationTargetType) { var typeName = extractContext .GetCLanguageTypeName(adjustorThunkTargetType); var delegationTargetTypeName = delegationTargetType .GetFullMemberName() .ManglingSymbolName(); return(new [] { new VirtualMethodInformation( delegationTargetTypeName, "IL2C_RuntimeCast", "void*", new[] { Utilities.KeyValue(typeName, "this__"), Utilities.KeyValue("IL2C_RUNTIME_TYPE_DECL*", "type"), }), } .Concat(adjustorThunkTargetType .EnumerateOrderedOverridedMethods() .Select(method => new VirtualMethodInformation( method.DeclaringType.MemberEquals(adjustorThunkTargetType) ? delegationTargetTypeName : method.DeclaringType .GetFullMemberName() .ManglingSymbolName(), method.GetOverloadedMethodName() .ManglingSymbolName(), extractContext.GetCLanguageTypeName( method.ReturnType), method.GetSafeParameters(adjustorThunkTargetType) .Select(parameter => Utilities.KeyValue( extractContext.GetCLanguageTypeName(parameter.ParameterType), parameter.Name)) .ToArray()))) .ToArray()); }
public static string GetGivenParameterDeclaration( RightExpressionGivenParameter[] parameters, IExtractContext extractContext, int offset) { return(string.Join(", ", parameters.Select(entry => { var rightExpression = extractContext.GetRightExpression( entry.TargetType, entry.SymbolInformation); if (rightExpression == null) { throw new InvalidProgramSequenceException( "Invalid parameter type: Offset={0}, StackType={1}, ParameterType={2}", offset, entry.SymbolInformation.TargetType.FullName, entry.TargetType.FullName); } return rightExpression; }))); }
public static string GetGivenParameterDeclaration( RightExpressionGivenParameter[] parameters, IExtractContext extractContext, ICodeInformation codeInformation) { return(string.Join(", ", parameters.Select(parameter => { var rightExpression = (parameter.Expression != null) ? extractContext.GetRightExpression(parameter.TargetType, parameter.SymbolInformation.TargetType, parameter.Expression) : extractContext.GetRightExpression(parameter.TargetType, parameter.SymbolInformation); if (rightExpression == null) { throw new InvalidProgramSequenceException( "Invalid parameter type: Location={0}, StackType={1}, ParameterType={2}", codeInformation.RawLocation, parameter.SymbolInformation.TargetType.FriendlyName, parameter.TargetType.FriendlyName); } return rightExpression; }))); }
public static void WriteHeader( TextWriter twHeader, TranslateContext translateContext, PreparedFunctions preparedFunctions, string indent) { IExtractContext extractContext = translateContext; var assemblyName = extractContext.Assembly.Name.Name; var safeSymbolName = assemblyName.Replace('.', '_').Replace('-', '_'); twHeader.WriteLine("#ifndef __MODULE_{0}__", safeSymbolName); twHeader.WriteLine("#define __MODULE_{0}__", safeSymbolName); twHeader.WriteLine(); foreach (var fileName in extractContext.EnumerateRequiredIncludeFileNames()) { twHeader.WriteLine("#include <{0}>", fileName); } var types = extractContext.Assembly.Modules .SelectMany(module => module.Types) .SelectMany(type => new[] { type }.Concat(type.NestedTypes)) // All types exclude privates .Where(type => type.IsValidDefinition() && (type.IsPublic || type.IsNestedPublic || type.IsNestedFamily || type.IsNestedFamilyOrAssembly)) .ToArray(); InternalConvertToPrototypes( twHeader, types, extractContext, preparedFunctions, method => method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly, indent); twHeader.WriteLine(); twHeader.WriteLine("#endif"); }
internal static void InternalWriteHeader( CodeTextWriter twHeader, TranslateContext translateContext, PreparedInformations prepared, bool includeAssemblyHeader) { IExtractContext extractContext = translateContext; var assemblyName = Utilities.GetMangledName(extractContext.Assembly.FriendlyName); twHeader.WriteLine("#ifndef __{0}_H__", assemblyName); twHeader.WriteLine("#define __{0}_H__", assemblyName); twHeader.SplitLine(); twHeader.WriteLine("#pragma once"); twHeader.SplitLine(); twHeader.WriteLine("#include <il2c.h>"); if (includeAssemblyHeader) { twHeader.SplitLine(); foreach (var fileName in extractContext.EnumerateRequiredIncludeFileNames()) { twHeader.WriteLine("#include <{0}>", fileName); } } // All types exclude privates PrototypeWriter.InternalConvertToPrototypes( twHeader, prepared.Types, type => type.IsCLanguagePublicScope, field => field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly, method => (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly) && prepared.Functions.ContainsKey(method)); twHeader.SplitLine(); twHeader.WriteLine("#endif"); twHeader.SplitLine(); }
public static string GetFunctionTypeString( string methodName, TypeReference returnType, Parameter[] parameters, IExtractContext extractContext) { var parametersString = string.Join( ", ", parameters.Select(parameter => string.Format( "{0} {1}", extractContext.GetCLanguageTypeName(parameter.ParameterType), parameter.Name))); var returnTypeName = extractContext.GetCLanguageTypeName(returnType); return(string.Format( "{0} (*{1})({2})", returnTypeName, methodName.ManglingSymbolName(), (parametersString.Length >= 1) ? parametersString : "void")); }
private static void InternalConvertFromAbstractFunction( TextWriter tw, IExtractContext extractContext, PreparedFunction preparedFunction, string indent) { var functionPrototype = Utilities.GetFunctionPrototypeString( GetFunctionNameByFunctionType(preparedFunction), preparedFunction.ReturnType, preparedFunction.Parameters, extractContext); tw.WriteLine(); tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// Abstract: {0}", preparedFunction.RawMethodName); tw.WriteLine(); tw.WriteLine(functionPrototype); tw.WriteLine("{"); tw.WriteLine( "{0}// WARNING: Pure virtual function called.", indent); tw.WriteLine( "{0}//TODO: throw : assert(0);", indent); if (preparedFunction.ReturnType.IsVoidType() == false) { tw.WriteLine( "{0}return ({1}){2};", indent, extractContext.GetCLanguageTypeName(preparedFunction.ReturnType), preparedFunction.ReturnType.IsNumericPrimitive() ? "0" : "NULL"); } tw.WriteLine("}"); }
private static void InternalConvertFromPInvokeFunction( TextWriter tw, IExtractContext extractContext, PreparedFunction preparedFunction, PInvokeInfo pinvokeInfo, string indent) { var functionPrototype = Utilities.GetFunctionPrototypeString( GetFunctionNameByFunctionType(preparedFunction), preparedFunction.ReturnType, preparedFunction.Parameters, extractContext); tw.WriteLine(); tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// P/Invoke: {0}", preparedFunction.RawMethodName); tw.WriteLine(); tw.WriteLine(functionPrototype); tw.WriteLine("{"); var arguments = string.Join( ", ", preparedFunction.Parameters .Select(parameter => parameter.GetMarshaledInExpression())); if (preparedFunction.ReturnType.IsVoidType()) { tw.WriteLine("{0}{1}({2});", indent, pinvokeInfo.EntryPoint, arguments); } else { tw.WriteLine("{0}return {1}({2});", indent, pinvokeInfo.EntryPoint, arguments); } tw.WriteLine("}"); }
internal static void InternalConvertFromMethod( TextWriter tw, IExtractContext extractContext, PreparedFunctions preparedFunctions, MethodDefinition method, string indent, DebugInformationOptions debugInformationOption = DebugInformationOptions.None) { var methodName = method.GetFullMemberName(); var preparedFunction = preparedFunctions.Functions[method]; // Write method body switch (preparedFunction.FunctionType) { case FunctionTypes.Standard: Debug.Assert(preparedFunction.PreparedILBodies != null); InternalConvertFromFunction( tw, extractContext, preparedFunction, indent, debugInformationOption); break; case FunctionTypes.Virtual: if (preparedFunction.PreparedILBodies != null) { InternalConvertFromFunction( tw, extractContext, preparedFunction, indent, debugInformationOption); } else { InternalConvertFromAbstractFunction( tw, extractContext, preparedFunction, indent); } break; case FunctionTypes.InterfaceVirtual: // Nothing to do break; case FunctionTypes.PInvoke: var pinvokeInfo = method.PInvokeInfo; if (pinvokeInfo == null) { throw new InvalidProgramSequenceException( "Missing DllImport attribute at P/Invoke entry: Method={0}", methodName); } InternalConvertFromPInvokeFunction( tw, extractContext, preparedFunction, pinvokeInfo, indent); break; } }
public static void WriteHeaders( CodeTextStorage storage, TranslateContext translateContext, PreparedInformations prepared) { IExtractContext extractContext = translateContext; var assemblyName = translateContext.Assembly.Name; var assemblyMangledName = translateContext.Assembly.MangledName; var typesByDeclaring = prepared.Types. GroupBy(type => type.DeclaringType ?? type). ToDictionary( g => g.Key, g => g.OrderByDependant(translateContext.Assembly).ToArray()); foreach (var g in prepared.Types. Where(type => type.DeclaringType == null). GroupBy(type => type.ScopeName)) { using (var _ = storage.EnterScope(g.Key)) { foreach (var type in g) { using (var twHeader = storage.CreateHeaderWriter(type.Name)) { var scopeName = Utilities.GetMangledName(type.ScopeName); twHeader.WriteLine( "// [14-1] This is {0} native code translated by IL2C, do not edit.", assemblyName); twHeader.SplitLine(); twHeader.WriteLine( "#include <{0}.h>", assemblyName); twHeader.SplitLine(); twHeader.WriteLine("#ifdef __cplusplus"); twHeader.WriteLine("extern \"C\" {"); twHeader.WriteLine("#endif"); twHeader.SplitLine(); twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [14-2] Type pre definitions:"); twHeader.SplitLine(); // All types exclude privates WriteTypePreDefinitions( twHeader, type, typesByDeclaring); twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [14-3] Type body definitions:"); twHeader.SplitLine(); twHeader.WriteLine( "#ifdef {0}_DECL_TYPE_BODY__", assemblyMangledName); twHeader.SplitLine(); InternalWriteHeader( twHeader, prepared, type, MemberScopes.Public, typesByDeclaring); twHeader.WriteLine("#endif"); twHeader.SplitLine(); twHeader.WriteLine("#ifdef __cplusplus"); twHeader.WriteLine("}"); twHeader.WriteLine("#endif"); twHeader.SplitLine(); twHeader.Flush(); } } } } }
public static void WriteCommonInternalHeader( CodeTextStorage storage, TranslateContext translateContext, PreparedInformations prepared, string assemblyName) { IExtractContext extractContext = translateContext; var annotatedAssemblyName = assemblyName + "_internal"; var annotatedAssemblyMangledName = Utilities.GetMangledName(annotatedAssemblyName); using (var twHeader = storage.CreateHeaderWriter(annotatedAssemblyName)) { twHeader.WriteLine( "// [13-1] This is {0} native code translated by IL2C, do not edit.", assemblyName); twHeader.SplitLine(); twHeader.WriteLine( "#ifndef __{0}_H__", annotatedAssemblyMangledName); twHeader.WriteLine( "#define __{0}_H__", annotatedAssemblyMangledName); twHeader.SplitLine(); twHeader.WriteLine("#pragma once"); twHeader.SplitLine(); twHeader.WriteLine("#include <{0}.h>", assemblyName); twHeader.SplitLine(); var constStrings = extractContext. ExtractConstStrings(). ToArray(); if (constStrings.Length >= 1) { twHeader.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [9-1-1] Const strings:"); twHeader.SplitLine(); foreach (var(symbolName, _) in constStrings) { twHeader.WriteLine( "extern System_String* const {0};", symbolName); } twHeader.SplitLine(); } var declaredValues = extractContext. ExtractDeclaredValues(). ToArray(); if (declaredValues.Length >= 1) { twHeader.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [12-1-1] Declared values:"); twHeader.SplitLine(); foreach (var information in declaredValues) { foreach (var declaredFields in information.DeclaredFields) { twHeader.WriteLine( "// {0}", declaredFields.FriendlyName); } var targetType = (information.HintTypes.Length == 1) ? information.HintTypes[0] : extractContext.MetadataContext.ByteType.MakeArray(); Debug.Assert(targetType.IsArray); var elementType = targetType.ElementType.ResolveToRuntimeType(); var values = Utilities.ResourceDataToSpecificArray(information.ResourceData, elementType); var lhs = targetType.GetCLanguageTypeName(information.SymbolName, true); twHeader.WriteLine( "extern const {0};", lhs); } twHeader.SplitLine(); } twHeader.WriteLine("#endif"); twHeader.Flush(); } }
public static void WriteCommonHeader( CodeTextStorage storage, TranslateContext translateContext, PreparedInformations prepared, string assemblyName) { IExtractContext extractContext = translateContext; var assemblyMangledName = Utilities.GetMangledName(assemblyName); using (var twHeader = storage.CreateHeaderWriter(assemblyName)) { twHeader.WriteLine( "// [13-1] This is {0} native code translated by IL2C, do not edit.", assemblyName); twHeader.SplitLine(); twHeader.WriteLine( "#ifndef __{0}_H__", assemblyMangledName); twHeader.WriteLine( "#define __{0}_H__", assemblyMangledName); twHeader.SplitLine(); twHeader.WriteLine("#pragma once"); twHeader.SplitLine(); // Write assembly references. var assemblies = extractContext.EnumerateRegisteredTypes(). SelectMany(entry => entry.Value). Distinct(). OrderByDependant(translateContext.Assembly). Select(type => type.DeclaringModule.DeclaringAssembly). Where(assembly => !assembly.Equals(translateContext.Assembly)). Distinct(). ToArray(); if (assemblies.Length >= 1) { twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [13-2] Assembly references:"); twHeader.SplitLine(); foreach (var assembly in assemblies) { twHeader.WriteLine("#include <{0}.h>", assembly.Name); } twHeader.SplitLine(); } // Write native headers from the NativeType/NativeMethod/NativeValue attributes. var importFileNames = extractContext.EnumerateRequiredImportIncludeFileNames().ToArray(); if (importFileNames.Length >= 1) { twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [13-3] Import native headers:"); twHeader.SplitLine(); foreach (var fileName in importFileNames) { twHeader.WriteLine("#include <{0}>", fileName); } twHeader.SplitLine(); } var types = prepared.Types. Where(type => type.DeclaringType == null). OrderByDependant(translateContext.Assembly). ToArray(); if (types.Length >= 1) { // Write pre definitions of type. twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [13-4] Type pre definitions:"); twHeader.SplitLine(); foreach (var type in types) { twHeader.WriteLine( "#include \"{0}/{1}/{2}.h\"", assemblyName, Utilities.GetCLanguageScopedPath(type.ScopeName), type.Name); } twHeader.SplitLine(); // Write body definitions of type. twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [13-5] Type body definitions:"); twHeader.SplitLine(); twHeader.WriteLine( "#define {0}_DECL_TYPE_BODY__ 1", assemblyMangledName); twHeader.SplitLine(); foreach (var type in types) { twHeader.WriteLine( "#include \"{0}/{1}/{2}.h\"", assemblyName, Utilities.GetCLanguageScopedPath(type.ScopeName), type.Name); } twHeader.SplitLine(); } twHeader.WriteLine("#endif"); twHeader.Flush(); } }
public static string WriteCommonInternalSourceCode( CodeTextStorage storage, TranslateContext translateContext, PreparedInformations prepared, string assemblyName) { IExtractContext extractContext = translateContext; using (var twSource = storage.CreateSourceCodeWriter(assemblyName + "_internal")) { var assemblyMangledName = Utilities.GetMangledName(assemblyName); twSource.WriteLine( "// [15-1] This is {0} native code translated by IL2C, do not edit.", assemblyName); twSource.SplitLine(); twSource.WriteLine( "#include <{0}.h>", assemblyName); twSource.WriteLine( "#include <{0}_internal.h>", assemblyName); twSource.SplitLine(); var constStrings = extractContext. ExtractConstStrings(). ToArray(); if (constStrings.Length >= 1) { twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// [9-1-2] Const strings:"); twSource.SplitLine(); foreach (var(symbolName, value) in constStrings) { twSource.WriteLine( "IL2C_CONST_STRING({0}, {1});", symbolName, Utilities.GetCLanguageExpression(value)); } twSource.SplitLine(); } var declaredValues = extractContext. ExtractDeclaredValues(). ToArray(); if (declaredValues.Length >= 1) { twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// [12-1-2] Declared values:"); twSource.SplitLine(); foreach (var information in declaredValues) { foreach (var declaredFields in information.DeclaredFields) { twSource.WriteLine( "// {0}", declaredFields.FriendlyName); } var targetType = (information.HintTypes.Length == 1) ? information.HintTypes[0] : extractContext.MetadataContext.ByteType.MakeArray(); Debug.Assert(targetType.IsArray); var elementType = targetType.ElementType.ResolveToRuntimeType(); var values = Utilities.ResourceDataToSpecificArray(information.ResourceData, elementType); var lhs = targetType.GetCLanguageTypeName(information.SymbolName, true); twSource.WriteLine( "const {0} =", lhs); using (var _ = twSource.Shift()) { twSource.WriteLine( "{0};", Utilities.GetCLanguageExpression(values)); } } twSource.SplitLine(); } twSource.Flush(); return(twSource.RelatedPath); } }
public static void WriteSourceCode( TextWriter twSource, TranslateContext translateContext, PreparedFunctions preparedFunctions, string indent, DebugInformationOptions debugInformationOption = DebugInformationOptions.Full) { IExtractContext extractContext = translateContext; foreach (var fileName in extractContext.EnumerateRequiredPrivateIncludeFileNames()) { twSource.WriteLine("#include \"{0}\"", fileName); } var assemblyName = extractContext.Assembly.Name.Name; twSource.WriteLine("#include \"{0}.h\"", assemblyName); twSource.WriteLine(); twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// Const strings:"); twSource.WriteLine(); foreach (var kv in extractContext.ExtractConstStrings()) { var escaped = Utilities.GetEscapedCString(kv.Value); twSource.WriteLine( "IL2C_CONST_STRING({0}, L\"{1}\");", kv.Key, escaped); } var allTypes = extractContext.Assembly.Modules .SelectMany(module => module.Types) .SelectMany(type => new[] { type }.Concat(type.NestedTypes)) .Where(type => type.IsValidDefinition()) .ToArray(); // All types exclude publics and internals (for file scope prototypes) var types = allTypes .Where(type => !(type.IsPublic || type.IsNestedPublic || type.IsNestedFamily || type.IsNestedFamilyOrAssembly)) .ToArray(); InternalConvertToPrototypes( twSource, types, extractContext, preparedFunctions, method => !(method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly), indent); twSource.WriteLine(); twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// Static fields:"); foreach (var type in allTypes.Where(type => !type.IsEnum)) { twSource.WriteLine(); // All static fields foreach (var field in type.Fields .Where(field => field.IsStatic)) { twSource.WriteLine( "{0};", Utilities.GetStaticFieldPrototypeString(field, true, extractContext)); } } twSource.WriteLine(); twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// Methods:"); foreach (var type in allTypes.Where(type => !type.IsEnum)) { twSource.WriteLine(); twSource.WriteLine("////////////////////////////////////////////////////////////"); twSource.WriteLine("// Type: {0}", type.GetFullMemberName()); // All methods and constructor exclude type initializer foreach (var method in type.Methods .Where(method => !method.IsConstructor || !method.IsStatic)) { InternalConvertFromMethod( twSource, extractContext, preparedFunctions, method, indent, debugInformationOption); } if (type.IsClass || type.IsValueType) { InternalConvertTypeHelper( twSource, extractContext, type, indent); } else if (type.IsInterface) { InternalConvertTypeHelperForInterface( twSource, type, indent); } } }
private static void InternalConvertFromDelegateInvoker( CodeTextWriter tw, IExtractContext extractContext, IMethodInformation method) { if (method.Parameters.Length == 0) { throw new InvalidProgramSequenceException( "Invalid delegate invoker. Name={0}", method.FriendlyName); } tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// [11-2] Delegate invoker: {0}", method.FriendlyName); tw.SplitLine(); // DIRTY: // Cause undefined symbol error at C compilation if "System.Delegate" type on the mscorlib assembly // contains the fields with different symbol name. var thisName = method.Parameters[0].ParameterName; tw.WriteLine(method.CLanguageFunctionPrototype); tw.WriteLine("{"); using (var _ = tw.Shift()) { tw.WriteLine( "il2c_assert({0} != NULL);", thisName); tw.WriteLine( "il2c_assert({0}->vptr0__ == &System_Delegate_VTABLE__);", thisName); tw.WriteLine( "il2c_assert({0}->count__ >= 1);", thisName); tw.SplitLine(); if (!method.ReturnType.IsVoidType) { if (method.ReturnType.IsReferenceType) { tw.WriteLine( "struct {0}_EXECUTION_FRAME__", method.CLanguageFunctionName); tw.WriteLine("{"); using (var __ = tw.Shift()) { tw.WriteLine("uint8_t objRefCount__;"); tw.WriteLine("uint8_t objRefRefCount__;"); tw.WriteLine("IL2C_EXECUTION_FRAME* pNext__;"); tw.WriteLine( "{0} result;", method.ReturnType.CLanguageTypeName); } tw.WriteLine("} frame__ = { 1, 0 };"); tw.WriteLine("il2c_link_execution_frame(&frame__);"); } else { tw.WriteLine( "{0} result;", method.ReturnType.CLanguageTypeName); } } tw.SplitLine(); tw.WriteLine( "uintptr_t index = 0;"); tw.WriteLine( "do", thisName); tw.WriteLine( "{"); using (var __ = tw.Shift()) { tw.WriteLine( "IL2C_METHOD_TABLE_DECL* pMethodtbl = &{0}->methodtbl__[index];", thisName); if (method.ReturnType.IsVoidType) { tw.WriteLine("if (pMethodtbl->target != NULL)"); using (var ___ = tw.Shift()) { tw.WriteLine( "((void (*)(System_Object*{0}))(pMethodtbl->methodPtr))(pMethodtbl->target{1});", string.Join(string.Empty, method.Parameters. Skip(1). Select(p => string.Format(", {0}", p.TargetType.CLanguageTypeName))), string.Join(string.Empty, method.Parameters. Skip(1). Select(p => string.Format(", {0}", p.ParameterName)))); } tw.WriteLine("else"); using (var ___ = tw.Shift()) { tw.WriteLine( "((void (*)({0}))(pMethodtbl->methodPtr))({1});", string.Join(", ", method.Parameters. Skip(1). Select(p => p.TargetType.CLanguageTypeName)), string.Join(", ", method.Parameters. Skip(1). Select(p => p.ParameterName))); } } else { tw.WriteLine("if (pMethodtbl->target != NULL)"); using (var ___ = tw.Shift()) { tw.WriteLine( "{0}result = (({1} (*)(System_Object*{2}))(pMethodtbl->methodPtr))(pMethodtbl->target{3});", method.ReturnType.IsReferenceType ? "frame__." : string.Empty, method.ReturnType.CLanguageTypeName, string.Join(string.Empty, method.Parameters. Skip(1). Select(p => string.Format(", {0}", p.TargetType.CLanguageTypeName))), string.Join(string.Empty, method.Parameters. Skip(1). Select(p => string.Format(", {0}", p.ParameterName)))); } tw.WriteLine("else"); using (var ___ = tw.Shift()) { tw.WriteLine( "{0}result = (({1} (*)({2}))(pMethodtbl->methodPtr))({3});", method.ReturnType.IsReferenceType ? "frame__." : string.Empty, method.ReturnType.CLanguageTypeName, string.Join(", ", method.Parameters. Skip(1). Select(p => p.TargetType.CLanguageTypeName)), string.Join(", ", method.Parameters. Skip(1). Select(p => p.ParameterName))); } } tw.WriteLine("index++;"); } tw.WriteLine("}"); tw.WriteLine("while (index < this__->count__);"); tw.SplitLine(); if (!method.ReturnType.IsVoidType) { if (method.ReturnType.IsReferenceType) { tw.WriteLine("il2c_unlink_execution_frame(&frame__);"); tw.WriteLine("return frame__.result;"); } else { tw.WriteLine("return result;"); } } } tw.WriteLine("}"); tw.SplitLine(); }
private static void InternalConvertType( TextWriter tw, IExtractContext extractContext, TypeDefinition declaredType, string indent) { if (declaredType.IsPrimitive || !(declaredType.IsValueType || declaredType.IsClass || declaredType.IsInterface)) { return; } var typeName = extractContext.GetCLanguageTypeName( declaredType, TypeNameFlags.Dereferenced) .ManglingSymbolName(); var rawTypeName = declaredType .GetFullMemberName() .ManglingSymbolName(); var typeString = declaredType.IsEnum ? "Enum" : declaredType.IsValueType ? "Struct" : declaredType.IsInterface ? "Interface" : "Class"; tw.WriteLine("////////////////////////////////////////////////////////////"); tw.WriteLine( "// {0}: {1}", typeString, declaredType.GetFullMemberName()); if (declaredType.IsEnum) { tw.WriteLine(); tw.WriteLine( "// {0} layout", typeString); tw.WriteLine( "typedef enum {0}", typeName); tw.WriteLine("{"); // Emit enum values foreach (var field in declaredType.Fields.Where(field => field.IsLiteral)) { tw.WriteLine( "{0}{1}_{2} = {3},", indent, typeName, field.Name, field.Constant); } tw.WriteLine( "}} {0};", typeName); tw.WriteLine(); } else { // IL2C vtable model case [1]: // // public class A : IB { // public int F1; // public string F2; // public virtual int Calc(int a, int b); // } // public interface IB { // int Calc(int a, int b); // } // // +----------------------+ // | IL2C_REF_HEADER | // +----------------------+ <-- this__ __A_VTABLE__ // | vptr0__ | -------------> +--------------------+ // +----------------------+ | ILC2_RuntimeCast() | // | vptr_A_IB__ | ----------+ | ToString() | // +----------------------+ | | GetHashCode() | // | int F1 | | | Finalize() | // | string F2 | | | Equals() | // +----------------------+ | | Calc() | // | +--------------------+ // | __A_IB_VTABLE__ // +--> +------------------------------+ // | ILC2_RuntimeCast() [with AT] | // | ToString() [with AT] | // | GetHashCode() [with AT] | // | Finalize() [with AT] | // | Equals() [with AT] | // | Calc() [with AT] | // +------------------------------+ tw.WriteLine(); tw.WriteLine( "// {0} vtable layout", typeString); tw.WriteLine("typedef const struct"); tw.WriteLine("{"); tw.WriteLine( "{0}/* internalcall */ void* (*IL2C_RuntimeCast)({1}* this__, IL2C_RUNTIME_TYPE_DECL* type);", indent, rawTypeName); var virtualMethods = declaredType .EnumerateOrderedOverridedMethods() .ToArray(); foreach (var method in virtualMethods) { var functionPrototype = Utilities.GetFunctionTypeString( method.GetOverloadedMethodName().ManglingSymbolName(), method.ReturnType, method.GetSafeParameters(declaredType), extractContext); tw.WriteLine( "{0}{1};", indent, functionPrototype); } tw.WriteLine( "}} __{0}_VTABLE_DECL__;", rawTypeName); var fields = declaredType .Traverse(type => type.BaseType?.Resolve()) .Reverse() .SelectMany(type => { var vptrs = type.Interfaces .Select(interfaceImpl => new { Name = string.Format( "vptr_{0}__", interfaceImpl.InterfaceType .GetFullMemberName() .ManglingSymbolName()), TypeName = string.Format( "__{0}_VTABLE_DECL__*", interfaceImpl.InterfaceType .GetFullMemberName() .ManglingSymbolName()) }); var thisFields = type.Fields .Where(field => !field.IsStatic) .Select(field => new { field.Name, TypeName = extractContext.GetCLanguageTypeName(field.FieldType) }); return(vptrs.Concat(thisFields)); }) .ToArray(); if ((declaredType.IsValueType == false) || (fields.Length >= 1)) { tw.WriteLine(); tw.WriteLine( "// {0} layout", typeString); tw.WriteLine( "struct {0}", typeName); tw.WriteLine("{"); // Emit vptr: if (declaredType.IsClass || declaredType.IsInterface) { tw.WriteLine( "{0}__{1}_VTABLE_DECL__* vptr0__;", indent, rawTypeName); } foreach (var field in fields) { tw.WriteLine( "{0}{1} {2};", indent, field.TypeName, field.Name); } tw.WriteLine("};"); tw.WriteLine(); } } var makrHandlerPrototype = string.Format( "extern IL2C_RUNTIME_TYPE_DECL __{0}_RUNTIME_TYPE__;", rawTypeName); tw.WriteLine(); tw.WriteLine( "// {0} runtime type information", typeString); tw.WriteLine(makrHandlerPrototype); }
private static void InternalConvertToPrototypes( TextWriter tw, TypeDefinition[] types, IExtractContext extractContext, PreparedFunctions preparedFunctions, Func <MethodDefinition, bool> predictMethod, string indent) { tw.WriteLine(); tw.WriteLine("#ifdef __cplusplus"); tw.WriteLine("extern \"C\" {"); tw.WriteLine("#endif"); tw.WriteLine(); tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); tw.WriteLine("// Types:"); tw.WriteLine(); // Output prototypes. foreach (var type in types.Where(type => !type.IsEnum)) { var typeName = extractContext.GetCLanguageTypeName(type, TypeNameFlags.Dereferenced) .ManglingSymbolName(); tw.WriteLine( "typedef struct {0} {0};", typeName); } // Output value type and object reference type. foreach (var type in types) { tw.WriteLine(); InternalConvertType( tw, extractContext, type, indent); } tw.WriteLine(); tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); tw.WriteLine("// Public static fields:"); foreach (var type in types.Where(type => !type.IsEnum)) { tw.WriteLine(); foreach (var field in type.Fields .Where(field => field.IsPublic && field.IsStatic)) { tw.WriteLine( "extern {0};", Utilities.GetStaticFieldPrototypeString(field, false, extractContext)); } } tw.WriteLine(); tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); tw.WriteLine("// Methods:"); foreach (var type in types.Where(type => !type.IsEnum)) { var rawTypeName = type .GetFullMemberName() .ManglingSymbolName(); var typeName = extractContext .GetCLanguageTypeName(type, TypeNameFlags.Dereferenced) .ManglingSymbolName(); tw.WriteLine(); tw.WriteLine( "// {0}", type.FullName); if (!type.IsInterface) { tw.WriteLine( "extern /* internalcall */ void __{0}_IL2C_MarkHandler__({1}* this__);", rawTypeName, typeName); } tw.WriteLine( "extern /* internalcall */ void* __{0}_IL2C_RuntimeCast__({1}* this__, IL2C_RUNTIME_TYPE_DECL* type);", rawTypeName, typeName); // TODO: Support enum type methods foreach (var method in type.Methods .Where(method => (!method.IsConstructor || !method.IsStatic) && predictMethod(method))) { var preparedFunction = preparedFunctions.Functions[method]; var functionPrototype = Utilities.GetFunctionPrototypeString( GetFunctionNameByFunctionType(preparedFunction), preparedFunction.ReturnType, preparedFunction.Parameters, extractContext); tw.WriteLine( "extern {0}{1};", method.IsVirtual ? "/* virtual */ " : string.Empty, functionPrototype); } var virtualMethods = type .EnumerateOrderedOverridedMethods() .Where(predictMethod) .ToArray(); foreach (var method in virtualMethods) { var fullMethodName = type .GetFullMemberName(method, MethodNameTypes.Index) .ManglingSymbolName(); var functionParametersDeclaration = string.Join( ", ", method.GetSafeParameters() .Select((parameter, index) => (index == 0) ? string.Format( "/* {0} */ {1}", extractContext.GetCLanguageTypeName(type), parameter.Name) : string.Format( "/* {0} */ {1}", extractContext.GetCLanguageTypeName(parameter.ParameterType), parameter.Name))); tw.WriteLine( "#define {0}({1}) \\", fullMethodName, functionParametersDeclaration); var methodName = method .GetOverloadedMethodName() .ManglingSymbolName(); var functionParameters = string.Join( ", ", method.GetSafeParameters() .Select(parameter => parameter.Name)); tw.WriteLine( "{0}((this__)->vptr0__->{1}({2}))", indent, methodName, functionParameters); } } tw.WriteLine(); tw.WriteLine("#ifdef __cplusplus"); tw.WriteLine("}"); tw.WriteLine("#endif"); }
private static void InternalConvertFromFunction( TextWriter tw, IExtractContext extractContext, PreparedFunction preparedFunction, string indent, DebugInformationOptions debugInformationOption) { var locals = preparedFunction.LocalVariables; var functionPrototype = Utilities.GetFunctionPrototypeString( GetFunctionNameByFunctionType(preparedFunction), preparedFunction.ReturnType, preparedFunction.Parameters, extractContext); tw.WriteLine(); tw.WriteLine("///////////////////////////////////////"); tw.WriteLine( "// {0}{1}", (preparedFunction.FunctionType == FunctionTypes.Virtual) ? "Virtual: " : string.Empty, preparedFunction.RawMethodName); tw.WriteLine(); tw.WriteLine(functionPrototype); tw.WriteLine("{"); tw.WriteLine("{0}//-------------------", indent); tw.WriteLine("{0}// Local variables:", indent); tw.WriteLine(); // Important NULL assigner (p = NULL): // Because these variables are pointer (of object reference). // So GC will traverse these variables just setup the stack frame. foreach (var local in preparedFunction.LocalVariables) { tw.WriteLine( "{0}{1} {2}{3};", indent, extractContext.GetCLanguageTypeName(local.TargetType), local.SymbolName, local.TargetType.IsValueType ? string.Empty : " = NULL"); } tw.WriteLine(); tw.WriteLine("{0}//-------------------", indent); tw.WriteLine("{0}// Evaluation stacks:", indent); tw.WriteLine(); foreach (var si in preparedFunction.Stacks) { tw.WriteLine( "{0}{1} {2}{3};", indent, extractContext.GetCLanguageTypeName(si.TargetType), si.SymbolName, si.TargetType.IsValueType ? string.Empty : " = NULL"); } var frameEntries = locals .Concat(preparedFunction.Stacks) .Where(local => !local.TargetType.IsValueType && !local.TargetType.IsPointer) .ToArray(); if (frameEntries.Length >= 1) { tw.WriteLine(); tw.WriteLine("{0}//-------------------", indent); tw.WriteLine("{0}// Setup stack frame:", indent); tw.WriteLine(); tw.WriteLine("{0}struct /* IL2C_EXECUTION_FRAME */", indent); tw.WriteLine("{0}{{", indent); tw.WriteLine("{0}{0}IL2C_EXECUTION_FRAME* pNext;", indent); tw.WriteLine("{0}{0}uint8_t targetCount;", indent); foreach (var frameEntry in frameEntries) { tw.WriteLine( "{0}{0}{1}* p{2};", indent, extractContext.GetCLanguageTypeName(frameEntry.TargetType), frameEntry.SymbolName); } tw.WriteLine("{0}}} __executionFrame__;", indent); tw.WriteLine(); tw.WriteLine("{0}__executionFrame__.targetCount = {1};", indent, frameEntries.Length); foreach (var frameEntry in frameEntries) { tw.WriteLine( "{0}__executionFrame__.p{1} = &{1};", indent, frameEntry.SymbolName); } tw.WriteLine("{0}il2c_link_execution_frame(&__executionFrame__);", indent); } tw.WriteLine(); tw.WriteLine("{0}//-------------------", indent); tw.WriteLine("{0}// IL body:", indent); tw.WriteLine(); var canWriteSequencePoint = true; foreach (var ilBody in preparedFunction.PreparedILBodies) { // Write label if available and used. if (preparedFunction.TryGetLabelName( ilBody.Label, out var labelName)) { tw.WriteLine("{0}:", labelName); } // Write the line preprocessor directive if available. if (canWriteSequencePoint && ilBody.SequencePoints.Any()) { var sp = ilBody.SequencePoints.First(); switch (debugInformationOption) { case DebugInformationOptions.Full: tw.WriteLine( "#line {0} \"{1}\"", sp.StartLine, sp.Document.Url.Replace("\\", "\\\\")); break; case DebugInformationOptions.CommentOnly: tw.WriteLine( "/* {0}({1}): */", sp.Document.Url.Replace("\\", "\\\\"), sp.StartLine); break; } canWriteSequencePoint = false; } if (debugInformationOption != DebugInformationOptions.None) { // Write debugging information. tw.WriteLine( "{0}/* {1} */", indent, ilBody); } // Generate source code fragments and write. var sourceCodes = ilBody.Generator(extractContext); foreach (var sourceCode in sourceCodes) { // Dirty hack: // Write unlink execution frame code if cause exiting method. if (sourceCode.StartsWith("return") && (frameEntries.Length >= 1)) { tw.WriteLine( "{0}il2c_unlink_execution_frame(&__executionFrame__);", indent); } tw.WriteLine( "{0}{1};", indent, sourceCode); canWriteSequencePoint = true; } } tw.WriteLine("}"); }
private static void InternalConvertTypeHelper( TextWriter tw, IExtractContext extractContext, TypeDefinition declaredType, string indent) { tw.WriteLine(); tw.WriteLine("//////////////////////"); tw.WriteLine("// Runtime helpers:"); var rawTypeName = declaredType .GetFullMemberName() .ManglingSymbolName(); var typeName = extractContext.GetCLanguageTypeName( declaredType, TypeNameFlags.Dereferenced); // Write RuntimeCast function: tw.WriteLine(); tw.WriteLine("// Runtime cast"); tw.WriteLine( "void* __{0}_IL2C_RuntimeCast__({1} this__, IL2C_RUNTIME_TYPE_DECL* type)", rawTypeName, extractContext.GetCLanguageTypeName( declaredType, TypeNameFlags.ForcePointer)); tw.WriteLine("{"); // RuntimeCast: this type. // TODO: inlining all base type comparer are better than base invoker? tw.WriteLine( "{0}// This type", indent); tw.WriteLine( "{0}if (type == il2c_typeof({1})) return this__;", indent, rawTypeName); // RuntimeCast: implemented interfaces. if (declaredType.Interfaces.Count >= 1) { tw.WriteLine(); tw.WriteLine( "{0}// Interface types", indent); foreach (var interfaceImpl in declaredType.Interfaces) { var rawInterfaceTypeName = interfaceImpl.InterfaceType .GetFullMemberName() .ManglingSymbolName(); // NOTE: // The virtual function pointer added offset from between vptr_TYPE__ and vptr0__. // If will invoke interface's virtual function, // the function is delegated "Adjust thunk" function, // it will recalculate this pointer offset. tw.WriteLine( "{0}if (type == il2c_typeof({1})) return (void*)&(this__->vptr_{1}__);", indent, rawInterfaceTypeName); } } var rawBaseTypeName = declaredType.BaseType .GetFullMemberName() .ManglingSymbolName(); // RuntimeCast: reflect base types. tw.WriteLine(); tw.WriteLine( "{0}// Delegate checking base types", indent); tw.WriteLine( "{0}return __{1}_IL2C_RuntimeCast__(({2})this__, type);", indent, rawBaseTypeName, extractContext.GetCLanguageTypeName( declaredType.BaseType, TypeNameFlags.ForcePointer)); tw.WriteLine("}"); // Write mark handler: var makrHandlerPrototype = string.Format( "void __{0}_IL2C_MarkHandler__({1} this__)", rawTypeName, extractContext.GetCLanguageTypeName(declaredType, TypeNameFlags.ForcePointer)); tw.WriteLine(); tw.WriteLine("// GC's mark handler"); tw.WriteLine(makrHandlerPrototype); tw.WriteLine("{"); var fields = declaredType.Fields .Where(field => !field.IsStatic && !field.FieldType.IsValueType) .ToArray(); if (fields.Length >= 1) { tw.WriteLine( "{0}// Try marking each object reference fields", indent); foreach (var field in fields) { tw.WriteLine( "{0}il2c_try_mark_from_handler(this__->{1});", indent, field.Name); } } // Invoke base class mark handler except System.Object and System.ValueType. var baseType = declaredType.BaseType; if (baseType != null) { if ((baseType.IsObjectType() || baseType.IsValueTypeType()) == false) { tw.WriteLine(); tw.WriteLine( "{0}// Delegate checking base types", indent); tw.WriteLine( "{0}__{1}_IL2C_MarkHandler__(({2})this__);", indent, rawBaseTypeName, extractContext.GetCLanguageTypeName(declaredType.BaseType)); } else { tw.WriteLine(); tw.WriteLine( "{0}/* Suppressed invoke base mark handler */", indent); } } tw.WriteLine("}"); // Write runtime type information tw.WriteLine(); tw.WriteLine("// Runtime type information"); tw.WriteLine( "IL2C_RUNTIME_TYPE_DECL __{0}_RUNTIME_TYPE__ = {{", rawTypeName); tw.WriteLine( "{0}\"{1}\",", indent, declaredType.GetFullMemberName()); tw.WriteLine( "{0}sizeof({1}),", indent, typeName); tw.WriteLine( "{0}/* internalcall */ (IL2C_MARK_HANDLER)__{1}_IL2C_MarkHandler__,", indent, rawTypeName); tw.WriteLine("};"); tw.WriteLine(); tw.WriteLine("//////////////////////"); tw.WriteLine("// VTables:"); // Write virtual methods tw.WriteLine(); tw.WriteLine( "// Vtable of {0}", declaredType.FullName); tw.WriteLine( "__{0}_VTABLE_DECL__ __{0}_VTABLE__ = {{", rawTypeName); var virtualMethods = GetVirtualMethods( extractContext, declaredType, declaredType); foreach (var method in virtualMethods) { tw.WriteLine( "{0}({1} (*)({2}))__{3}_{4}__,", indent, method.ReturnTypeName, string.Join(", ", method.Parameters.Select(p => p.Key)), method.TypeName, method.Name); } tw.WriteLine("};"); foreach (var interfaceType in declaredType.Interfaces .Select(interfaceImpl => interfaceImpl.InterfaceType)) { var rawInterfaceTypeName = interfaceType .GetFullMemberName() .ManglingSymbolName(); var interfaceVirtualMethods = GetVirtualMethods( extractContext, interfaceType, declaredType); foreach (var method in interfaceVirtualMethods) { // Adjustor thunk will not invoke direct, so try to emit static function. tw.WriteLine(); tw.WriteLine( "// Adjustor thunk: {0}.{1}", method.TypeName, method.Name); tw.WriteLine( "static {0} __{1}_{2}_AT_{3}__(", method.ReturnTypeName, method.TypeName, method.Name, rawInterfaceTypeName); tw.WriteLine( "{0}{1})", indent, string.Join( ", ", method.Parameters.Select(parameter => string.Format( "{0} {1}", parameter.Key, parameter.Value)))); tw.WriteLine( "{"); tw.WriteLine( "{0}{1}__{2}_{3}__({4});", indent, (method.ReturnTypeName != "void") ? "return " : string.Empty, method.TypeName, method.Name, string.Join( ", ", method.Parameters.Select((parameter, index) => (index == 0) // Adjust vptr offset with il2c_cast_from_interface() macro. ? string.Format( "({0}*)il2c_cast_from_interface({1}, {2}, {3})", method.TypeName, rawTypeName, rawInterfaceTypeName, parameter.Value) : parameter.Value))); tw.WriteLine( "}"); } tw.WriteLine(); tw.WriteLine( "// Vtable of {0} (with adjustor thunk)", interfaceType.FullName); tw.WriteLine( "__{0}_VTABLE_DECL__ __{1}_{0}_VTABLE__ = {{", rawInterfaceTypeName, rawTypeName); foreach (var method in interfaceVirtualMethods) { tw.WriteLine( "{0}__{1}_{2}_AT_{3}__,", indent, method.TypeName, method.Name, rawInterfaceTypeName); } tw.WriteLine("};"); } }