private static void InternalWriteHeader( CodeTextWriter twHeader, PreparedInformations prepared, ITypeInformation targetType, MemberScopes memberScope, IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring) { if (typesByDeclaring.TryGetValue(targetType, out var types)) { foreach (var type in types) { // The nested types have to declare before outer types. if (!type.Equals(targetType)) { InternalWriteHeader( twHeader, prepared, type, memberScope, typesByDeclaring); } // Write value type and object reference type. TypeWriter.WriteTypeDefinitions( twHeader, type); // Write type members. TypeWriter.WriteMemberDefinitions( twHeader, type, field => true, method => // Except type initializer !(method.IsConstructor && method.IsStatic) && prepared.Functions.ContainsKey(method)); // TODO: The internal or private members can separate into the internal headers. //field => field.CLanguageMemberScope == memberScope, //method => (method.CLanguageMemberScope == memberScope) && prepared.Functions.ContainsKey(method)); } } }
private static void InternalWriteSourceCode( CodeTextWriter twSource, IExtractContextHost extractContext, PreparedInformations prepared, ITypeInformation targetType, DebugInformationOptions debugInformationOption, IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring) { // TODO: invalid sequence for multiple nested types. if (typesByDeclaring.TryGetValue(targetType, out var types)) { foreach (var type in types) { // The nested types have to declare before outer types. if (!type.Equals(targetType)) { InternalWriteSourceCode( twSource, extractContext, prepared, type, debugInformationOption, typesByDeclaring); } twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine( "// [9-1] Type: {0}", targetType.FriendlyName); twSource.SplitLine(); twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// [9-2] File scope prototypes:"); twSource.SplitLine(); // Write type members. TypeWriter.WriteMemberDefinitions( twSource, type, field => field.CLanguageMemberScope == MemberScopes.File, method => (method.CLanguageMemberScope == MemberScopes.File) && prepared.Functions.ContainsKey(method)); // All static fields except enum and native value. if (!type.IsEnum) { var staticFields = type.Fields. Where(field => field.IsStatic && (field.NativeValue == null)). ToArray(); if (staticFields.Length >= 1) { twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// [9-3] Static field handlers:"); twSource.SplitLine(); var staticFieldsName = type.MangledUniqueName + "_STATIC_FIELDS"; twSource.WriteLine( "static volatile uintptr_t {0}_initializerCount__ = 0;", staticFieldsName); twSource.SplitLine(); twSource.WriteLine( "static struct {0}_DECL__ /* IL2C_STATIC_FIELDS */", staticFieldsName); twSource.WriteLine("{"); var objrefStaticFields = staticFields. Where(field => field.FieldType.IsReferenceType). ToArray(); var valueTypeStaticFields = staticFields. Where(field => field.FieldType.IsValueType && field.FieldType.IsRequiredTraverse). ToArray(); var otherStaticFields = new HashSet <IFieldInformation>(staticFields. Except(objrefStaticFields). Except(valueTypeStaticFields)); using (var _ = twSource.Shift()) { twSource.WriteLine("IL2C_STATIC_FIELDS* pNext__;"); twSource.WriteLine("const uint16_t objRefCount__;"); twSource.WriteLine("const uint16_t valueCount__;"); if (objrefStaticFields.Length >= 1) { twSource.WriteLine("//-------------------- objref"); foreach (var field in objrefStaticFields) { twSource.WriteLine( "{0} {1};", field.FieldType.CLanguageTypeName, field.MangledName); } } if (valueTypeStaticFields.Length >= 1) { twSource.WriteLine("//-------------------- value type"); foreach (var field in valueTypeStaticFields) { twSource.WriteLine( "{0} {1};", field.FieldType.CLanguageTypeName, field.MangledName); } } } twSource.WriteLine( "}} {0}__ = {{ NULL, {1}, {2} }};", staticFieldsName, objrefStaticFields.Length, valueTypeStaticFields.Length); twSource.SplitLine(); foreach (var field in otherStaticFields) { twSource.WriteLine( "static {0} {1};", field.FieldType.CLanguageTypeName, field.MangledUniqueName); } twSource.SplitLine(); foreach (var field in staticFields) { twSource.WriteLine( "{0}* {1}_HANDLER__(void)", field.FieldType.CLanguageTypeName, field.MangledUniqueName); twSource.WriteLine("{"); using (var _ = twSource.Shift()) { // TODO: Have to guard race condition for the multi threading feature. twSource.WriteLine( "if (il2c_unlikely__({0}_initializerCount__ != *il2c_initializer_count))", staticFieldsName); twSource.WriteLine("{"); using (var __ = twSource.Shift()) { twSource.WriteLine( "{0}_initializerCount__ = *il2c_initializer_count;", staticFieldsName); twSource.WriteLine( "il2c_register_static_fields(&{0}__);", staticFieldsName); var typeInitializer = type.DeclaredMethods. FirstOrDefault(method => method.IsConstructor && method.IsStatic); if (typeInitializer != null) { twSource.WriteLine( "{0}();", typeInitializer.CLanguageFunctionFullName); } } twSource.WriteLine("}"); if (otherStaticFields.Contains(field)) { twSource.WriteLine( "return &{0};", field.MangledUniqueName); } else { twSource.WriteLine( "return &{0}__.{1};", staticFieldsName, field.MangledName); } } twSource.WriteLine("}"); twSource.SplitLine(); } } } twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////"); twSource.WriteLine("// [9-4] Type: {0}", type.FriendlyName); twSource.SplitLine(); // All methods and constructor exclude type initializer foreach (var method in type.DeclaredMethods. Where(method => prepared.Functions.ContainsKey(method))) { FunctionWriter.InternalConvertFromMethod( twSource, extractContext, prepared, method, debugInformationOption); } if (type.IsClass || type.IsValueType) { TypeHelperWriter.InternalConvertTypeHelper( twSource, type); } else if (type.IsInterface) { TypeHelperWriter.InternalConvertTypeHelperForInterface( twSource, type); } twSource.SplitLine(); } } }