public static MrType GetComposableFactoryType(MrType type) { var factories = GetFactories(type); var ca = factories.FirstOrDefault(f => f.Kind == "ComposableAttribute"); return(ca?.Type); }
private void WriteType(MrType t) { var name = ""; var gargs = t.GetGenericArguments(); var gparams = t.GetGenericTypeParameters(); name = GetSimpleTypeName(t, gargs, gparams); writer.WriteStartElement("type"); if (t.IsArray) { writer.WriteAttributeString("array", "true"); name = name.Replace("[]", ""); } writer.WriteAttributeString("name", name); if (!gargs.IsEmpty) { writer.WriteAttributeString("generic", "true"); writer.WriteStartElement("params"); foreach (var p in gparams) { WriteType(p); } writer.WriteEndElement(); } else { } writer.WriteEndElement(); }
public static string GetCppWinRTType(MrType t) { var primitiveTypes = new Dictionary <string, string>() { { "System.String", "winrt::hstring" }, { "System.Boolean", "bool" }, { "System.Int32", "int32_t" }, { "System.Int64", "int64_t" }, { "System.Double", "double" }, { "System.Single", "float" }, { "System.Uri", "winrt::Windows::Foundation::Uri" }, { "System.Object", "winrt::Windows::Foundation::IInspectable" }, }; if (t.GetFullName() == $"{XamlNames.XamlNamespace}.Controls.Maps.MapStyle") { // MapStyle has a bug where it doesn't support coercion from int } else if (t.IsEnum) { return("int32_t"); } else if (t.GetFullName() == "System.Nullable`1") { return(GetCppWinRTType(t.GetGenericTypeParameters().First())); } if (primitiveTypes.ContainsKey(t.GetFullName())) { return(primitiveTypes[t.GetFullName()]); } return($"winrt::{t.GetFullName().Replace(".", "::")}"); }
private static IEnumerable <MrProperty> GetAttachedDPCandidates(MrType dpType, MrType type) { type.GetMethodsAndConstructors(out var methods, out var ctors); return(type.GetProperties().Where(prop => { if (prop.GetName().EndsWith("Property") && prop.GetPropertyType() == dpType) { var propName = prop.GetName().Substring(0, prop.GetName().LastIndexOf("Property")); return methods.Any(x => x.GetName() == $"Set{propName}" && x.GetParsedMethodAttributes().IsStatic); } return false; })); }
private static List <FactoryInfo> GetFactories(MrType t) { var d = new List <FactoryInfo>(); foreach (var ca in t.GetCustomAttributes()) { ca.GetNameAndNamespace(out var name, out var ns); if (ns != "Windows.Foundation.Metadata") { continue; } ca.GetArguments(out var _fixed, out var named); var factoryInfo = new FactoryInfo(); factoryInfo.Kind = name; // factoryInfo.Type = GetSystemType(signature); if (name == "ActivatableAttribute") { factoryInfo.Activatable = true; } else if (name == "StaticAttribute") { factoryInfo.Statics = true; factoryInfo.Type = (MrType)_fixed[0].Value; } else if (name == "ComposableAttribute") { factoryInfo.Composable = true; factoryInfo.Type = (MrType)_fixed[0].Value; } else { continue; } d.Add(factoryInfo); } return(d); }
private static string MapManagedTypeToWinRtType(MrType t) { var map = new Dictionary <string, string> { { typeof(Object).FullName, "Windows.Foundation.IInspectable" }, { "System.Collections.Generic.IList`1", "Windows.Foundation.Collections.IVector`1" }, { "System.Collections.Generic.IReadOnlyList`1", "Windows.Foundation.Collections.IVectorView`1" }, { "System.Collections.Generic.IDictionary`2", "Windows.Foundation.Collections.IMap`2" }, { "System.Collections.Generic.IReadOnlyDictionary`2", "Windows.Foundation.Collections.IMapView`2" }, }; if (map.ContainsKey(t.GetFullName())) { return(map[t.GetFullName()]); } if (t.GetNamespace() == "System") { return(t.GetName()); } else { return(t.GetFullName()); } }
private static string GetSimpleTypeName(MrType t, ImmutableArray <MrType> gargs, ImmutableArray <MrType> gparams) { string name; if (t.IsTypeCode) { name = t.TypeCode.ToString(); } else if (t.GetNamespace() == "System") { name = MapManagedTypeToWinRtType(t); } else if (!gargs.IsEmpty || !gparams.IsEmpty) { name = MapManagedTypeToWinRtType(t); name = name.Substring(0, name.IndexOf('`')); } else { name = t.GetFullName(); } return(name); }
string GetTypeKind(MrType t) { if (t.IsClass && t.GetInvokeMethod() != null && t.GetBaseType().GetName() == "MulticastDelegate") { return("delegate"); } if (t.IsClass) { return("class"); } else if (t.IsInterface) { return("interface"); } else if (t.IsEnum) { return("enum"); } else if (t.IsStruct) { return("struct"); } throw new ArgumentException(); }
private static bool IsExclusiveInterface(MrType t) { return(t.IsInterface && t.GetCustomAttributes().Any(IsExclusiveToAttribute)); }
private static bool IsAttribute(MrType t) { return(t.GetBaseType() != null && t.GetBaseType().GetFullName() == typeof(Attribute).FullName); }
private static void WriteTypes(MrAssembly testAssembly, StringBuilder result) { foreach (var mrType in testAssembly.GetAllTypes()) { result.AppendLine(); if (mrType.IsPublic) { result.Append("public "); } var classKind = ""; if (mrType.IsStruct) { classKind = "struct"; } else if (mrType.IsClass) { classKind = "class"; } else if (mrType.IsInterface) { classKind = "interface"; } else if (mrType.IsEnum) { classKind = "enum"; } else { Assert.IsTrue(false); } result.Append($"{classKind} {mrType.GetPrettyFullName()}"); if (mrType.GetBaseType() != null) { result.Append($" : {mrType.GetBaseType().GetPrettyFullName()}"); } result.AppendLine(); result.AppendLine($" {mrType.Attributes.ToString()}"); var customAttributes = mrType.GetCustomAttributes(); foreach (var customAttribute in customAttributes) { customAttribute.GetNameAndNamespace(out var name, out var ns); customAttribute.GetArguments(out var fixedArguments, out var namedArguments); if (fixedArguments.IsEmpty && namedArguments.IsEmpty) { result.AppendLine($" [{name}]"); } else { var allArguments = fixedArguments .Select(fa => $"{fa.Item2.ToString()}") .Union(namedArguments.Select(na => $"{na.Item1}={na.Item2}")); result.AppendLine($" [{name}({string.Join(", ", allArguments)})]"); } } var interfaces = mrType.GetInterfaces(); foreach (var iface in interfaces) { result.AppendLine($" {iface.GetPrettyFullName()}"); } mrType.GetMethodsAndConstructors(out var methods, out var constructors); foreach (var constructor in constructors) { result.Append($" {constructor.DeclaringType.GetPrettyFullName()}("); var parameters = constructor.GetParameters(); WriteParameters(parameters, result); result.AppendLine(")"); } foreach (var property in mrType.GetProperties()) { var propertyName = property.GetName(); MrType itemPropertyType = null; if (propertyName == "Item") { itemPropertyType = property.GetItemType(publicishOnly: true); } if (itemPropertyType == null) { result.Append($" {property.GetPropertyType().GetPrettyFullName()} {propertyName} {{ get; "); if (property.Setter != null) { result.Append($"set; "); } result.AppendLine("}"); } else { result.AppendLine($" {property.GetPropertyType().GetPrettyFullName()} this.[{itemPropertyType}]"); } } foreach (var ev in mrType.GetEvents()) { result.AppendLine($" {ev.GetEventType().GetPrettyFullName()} {ev.GetName()} {{ add; remove; }}"); } foreach (var method in methods) { result.Append(" "); WriteMethodAttributes(method.MethodDefinition.Attributes, result); result.Append($"{method.ReturnType} {method.GetName()}("); var parameters = method.GetParameters(); WriteParameters(parameters, result); result.AppendLine(")"); } foreach (var field in mrType.GetFields()) { if (mrType.IsEnum) { if (!field.IsSpecialName) // Ignore special value__ field { var value = field.GetConstantValue(out var constantTypeCode); result.AppendLine($" {field.GetName()} = {value},"); } } else { result.AppendLine($" {field.GetFieldType().GetPrettyFullName()} {field.GetName()};"); } } } }
private void DumpTypes(Version version) { var start = DateTime.Now; Config = JsonDocument.Parse(File.ReadAllText(ConfigFileName), new JsonDocumentOptions() { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip }); var context = new MrLoadContext(true); context.FakeTypeRequired += (sender, e) => { var ctx = sender as MrLoadContext; if (e.AssemblyName == "Windows.Foundation.FoundationContract" || e.AssemblyName == "Windows.Foundation.UniversalApiContract") { e.ReplacementType = ctx.GetTypeFromAssembly(e.TypeName, "Windows"); } }; var windows_winmd = context.LoadAssemblyFromPath(Windows_winmd); var winmds = winmdPaths.Select(winmdPath => context.LoadAssemblyFromPath(winmdPath)).ToList(); // ToList realizes the list which is needs to happen before FinishLoading is called context.FinishLoading(); var typesPerAssembly = winmds.Select(winmd => winmd.GetAllTypes().Skip(1)); var types = typesPerAssembly.Count() != 0 ? typesPerAssembly.Aggregate((l1, l2) => l1.Union(l2)) : new MrType[] { }; var windows_winmdTypes = windows_winmd.GetAllTypes().Skip(1); if (winmdPaths.Count != 0) { types = types.Union(windows_winmdTypes); } else { types = windows_winmdTypes; } Util.LoadContext = context; foreach (var entry in Config.RootElement.GetProperty("commands").EnumerateObject()) { var commands = new List <Command>(); foreach (var c in entry.Value.EnumerateArray()) { var command = new Command { Name = c.GetProperty("name").GetString() }; if (c.TryGetProperty("args", out var value)) { command.TSArgTypes = ConvertJSONToTSType(value); } commands.Add(command); } Util.commands[GetTypeNameFromJsonProperty(entry)] = commands; } var fakeProps = new List <MrProperty>(); foreach (var entry in Config.RootElement.GetProperty("propNameMapping").EnumerateObject()) { Util.propNameMap[GetTypeNameFromJsonProperty(entry)] = entry.Value.GetString(); } foreach (var entry in Config.RootElement.GetProperty("fakeProps").EnumerateArray()) { var value = GetTypeNameFromJson(entry); var typeName = value.Substring(0, value.LastIndexOf('.')); var propName = value.Substring(value.LastIndexOf('.') + 1); fakeProps.Add(GetProperty(context, typeName, propName)); } ; var syntheticProps = new List <SyntheticProperty>(); foreach (var entry in Config.RootElement.GetProperty("syntheticProps").EnumerateArray()) { var declaringTypes = entry.GetProperty("declaringType"); string name = entry.GetProperty("name").GetString(); MrType propertyType = entry.TryGetProperty("propertyType", out var propTypeJson) ? context.GetType(GetTypeNameFromJson(propTypeJson)) : null; if (name.IndexOf('.') != -1) { var propTypeName = name.Substring(0, name.LastIndexOf('.')); var propName = name.Substring(name.LastIndexOf('.') + 1); var propType = context.GetType(propTypeName); var prop = propType.GetProperties().First(p => p.GetName() == propName); if (prop.GetPropertyType() != propertyType) { throw new ArgumentException($"The property type for {name} was expected to be {prop.GetPropertyType()}, but was specified as {propertyType}"); } } string fakePropertyType = entry.TryGetProperty("fakePropertyType", out var fakePropType) ? fakePropType.GetString() : null; string comment = entry.TryGetProperty("comment", out var commentElement) ? commentElement.GetString() : ""; if (declaringTypes.ValueKind == JsonValueKind.Array) { foreach (var declaringType in declaringTypes.EnumerateArray()) { var sp = new SyntheticProperty { Name = name, DeclaringType = context.GetType(GetTypeNameFromJson(declaringType)), PropertyType = propertyType, FakePropertyType = fakePropertyType, Comment = comment, }; syntheticProps.Add(sp); } } else { var sp = new SyntheticProperty { Name = name, DeclaringType = context.GetType(GetTypeNameFromJson(declaringTypes)), PropertyType = propertyType, FakePropertyType = fakePropertyType, Comment = comment, }; syntheticProps.Add(sp); } } Console.WriteLine("Generating projections for the following WinMD files:"); Console.WriteLine($"- {Windows_winmd}"); foreach (var path in winmdPaths) { Console.WriteLine($"- {Path.GetFullPath(path)}"); } Console.WriteLine(); var properties = new List <SyntheticProperty>(); PrintVerbose("Enumerating attached properties"); DiscoverAttachedProperties(context, types); PrintVerbose($"Parsing configuration from {ConfigFileName}"); foreach (var entry in Config.RootElement.GetProperty("attachedProps").EnumerateObject()) { var propName = GetTypeNameFromJsonProperty(entry); var attachedDPs = Util.AttachedProperties.Where(p => Util.MinusPropertySuffix(Util.GetPropFullName(p)).StartsWith(propName)); foreach (var attachedDP in attachedDPs) { var type = attachedDP.DeclaringType; var simpleName = attachedDP.GetName().Substring(0, attachedDP.GetName().LastIndexOf("Property")); type.GetMethodsAndConstructors(out var methods, out var ctors); var propType = methods.First(m => m.GetName() == $"Get{simpleName}").ReturnType; if (entry.Value.ValueKind == JsonValueKind.Array) { foreach (var onTypeEntry in entry.Value.EnumerateArray()) { var sp = new SyntheticProperty { Name = simpleName, DeclaringType = context.GetType(GetTypeNameFromJson(onTypeEntry)), PropertyType = propType, Property = attachedDP, Comment = $"Attached property: ${propName}", }; properties.Add(sp); } } else { var onType = GetTypeNameFromJson(entry.Value); var sp = new SyntheticProperty { Name = simpleName, DeclaringType = context.GetType(onType), PropertyType = propType, Property = attachedDP, Comment = $"Attached property: {propName}", }; properties.Add(sp); } } } foreach (var entry in Config.RootElement.GetProperty("typeMapping").EnumerateArray()) { Util.TypeMapping[GetTypeNameFromJson(entry)] = new TypeMapping() { VM = Enum.Parse <ViewManagerPropertyType>(entry.GetProperty("VM").GetString()), TS = entry.GetProperty("TS").GetString(), }; } var baseClassesToProject = new List <string>(); foreach (var entry in Config.RootElement.GetProperty("baseClasses").EnumerateArray()) { var name = GetTypeNameFromJson(entry); baseClassesToProject.Add(name); } ; var syntheticEvents = new List <SyntheticProperty>(); foreach (var entry in Config.RootElement.GetProperty("syntheticEvents").EnumerateObject()) { var val = GetTypeNameFromJsonProperty(entry); var typeName = val.Substring(0, val.LastIndexOf('.')); var eventName = val.Substring(val.LastIndexOf('.') + 1); syntheticEvents.Add(new SyntheticProperty() { Name = eventName, DeclaringType = context.GetType(typeName), FakePropertyType = entry.Value.GetString(), }); } var xamlTypes = types.Where(type => baseClassesToProject.Any(b => Util.DerivesFrom(type, b)) || type.GetFullName() == XamlNames.TopLevelProjectedType).ToList(); var generatedDirPath = Path.GetFullPath(cppOutPath ?? Path.Join(PackageRoot, @"windows\ReactNativeXaml\Codegen")); var packageSrcPath = Path.GetFullPath(tsOutPath ?? Path.Join(PackageRoot, @"src")); PrintVerbose("Filtering types"); var creatableTypes = xamlTypes.Where(x => Util.HasCtor(x)).ToList(); PrintVerbose("Sorting types"); creatableTypes.Sort((a, b) => a.GetFullName().CompareTo(b.GetFullName())); foreach (var entry in Config.RootElement.GetProperty("eventArgsMethods").EnumerateObject()) { Util.eventArgsMethods.Add(GetTypeNameFromJsonProperty(entry), entry.Value.EnumerateArray().Select(x => x.GetString())); } var events = new List <MrEvent>(); var eventArgProps = new List <SyntheticProperty>(); PrintVerbose("Enumerating properties and events"); foreach (var type in xamlTypes) { var props = type.GetProperties(); var propsToAdd = props.Where(p => Util.ShouldEmitPropertyMetadata(p)); foreach (var p in propsToAdd) { properties.Add(new SyntheticProperty() { Name = Util.GetPropFullName(p), DeclaringType = p.DeclaringType, Property = p, }); } var eventsToAdd = type.GetEvents().Where(e => Util.ShouldEmitEventMetadata(e)); foreach (var e in eventsToAdd) { var handlerDelegate = e.GetEventType(); var invoke = handlerDelegate.GetInvokeMethod(); if (invoke != null) { var parameters = invoke.GetParameters(); if (parameters.Length == 2 && (parameters[1].GetParameterName().EndsWith("args") || parameters[1].GetParameterType().GetName().EndsWith("Args"))) { Util.FoundEventArgsType(parameters[1].GetParameterType()); } else if (parameters.Length == 1 && parameters[0].GetParameterType().GetName().EndsWith("Args")) { Util.FoundEventArgsType(parameters[0].GetParameterType()); } else { throw new ArgumentException($"Couldn't infer event arg type for event {e.GetName()}"); } } else if (handlerDelegate.GetFullName() == "System.EventHandler`1") { var paramType = handlerDelegate.GetGenericTypeParameters(); if (paramType.Length != 1) { throw new ArgumentException($"Couldn't infer EventHandler generic type for event {e.GetName()}"); } Util.FoundEventArgsType(paramType[0]); } } events.AddRange(eventsToAdd); } foreach (var type in Util.eventArgsTypes) { var props = type.GetProperties(); var propsToAdd = props .Where(p => Util.IsInstanceProperty(p)) .Select(p => new SyntheticProperty() { Name = p.GetName(), DeclaringType = p.DeclaringType, Property = p, }); eventArgProps.AddRange(propsToAdd); foreach (var p in propsToAdd.Where(p => p.Property.GetPropertyType().IsEnum).Select(p => p.Property.GetPropertyType())) { Util.VisitEnum(p); } } properties.Sort(CompareProps); eventArgProps.Sort(CompareProps); PrintVerbose("Generating projection"); foreach (var entry in Config.RootElement.GetProperty("fakeEnums").EnumerateArray()) { var typeName = GetTypeNameFromJson(entry.GetProperty("name")); FakeEnum fe; if (typeName.IndexOf('.') != -1) { var type = context.GetType(typeName); if (type.IsEnum) { var values = type.GetFields().Skip(1); fe = new FakeEnum() { Name = typeName.Substring(typeName.LastIndexOf('.') + 1), Values = values.ToDictionary <MrField, string, int>(f => f.GetName(), f => (int)f.GetConstantValue(out var _)), }; } else { throw new ArgumentException($"Type {typeName} is not an enum"); } } else { fe = new FakeEnum() { Name = typeName, Values = ToDictionary(entry.GetProperty("values").EnumerateObject()), }; } Util.fakeEnums.Add(fe); } var propsGen = new TSProps(xamlTypes, properties, fakeProps, syntheticProps, syntheticEvents).TransformText(); var typesGen = new TSTypes(xamlTypes).TransformText(); var typeCreatorGen = new TypeCreator(creatableTypes).TransformText(); var propertiesGen = new TypeProperties(properties, fakeProps, syntheticProps).TransformText(); var enumsGen = new TypeEnums().TransformText(); var tsEnumsGen = new TSEnums().TransformText(); var eventsGen = new TypeEvents(events, syntheticEvents).TransformText(); var eventPropsGen = new EventArgsTypeProperties(eventArgProps).TransformText(); var versionGen = new VersionHeader() { Version = version }.TransformText(); PrintVerbose("Updating files"); if (!Directory.Exists(generatedDirPath)) { Directory.CreateDirectory(generatedDirPath); } var changes = false; changes |= UpdateFile(Path.Join(generatedDirPath, "TypeCreator.g.cpp"), typeCreatorGen); changes |= UpdateFile(Path.Join(generatedDirPath, "TypeProperties.g.h"), propertiesGen); changes |= UpdateFile(Path.Join(generatedDirPath, "TypeEvents.g.h"), eventsGen); changes |= UpdateFile(Path.Join(generatedDirPath, "EventArgsTypeProperties.g.h"), eventPropsGen); changes |= UpdateFile(Path.Join(generatedDirPath, "TypeEnums.g.h"), enumsGen); changes |= UpdateFile(Path.Join(generatedDirPath, "Version.g.h"), versionGen); changes |= UpdateFile(Path.Join(packageSrcPath, "Enums.ts"), tsEnumsGen.Replace("\r\n", "\n")); changes |= UpdateFile(Path.Join(packageSrcPath, "Props.ts"), propsGen.Replace("\r\n", "\n")); changes |= UpdateFile(Path.Join(packageSrcPath, "Types.tsx"), typesGen.Replace("\r\n", "\n")); if (!changes) { PrintVerbose("\nNo changes were required."); } PrintVerbose($"Done in {(DateTime.Now - start).TotalSeconds}s."); }
static void WriteType(MrType mrType, StringBuilder result, bool publicishOnly = true) { result.AppendLine(); // Write out "public class Foo " or "enum Bar" etc if (mrType.IsPublic) { result.Append("public "); } if (mrType.IsInternal) { result.Append("internal "); } if (mrType.IsProtected) // Nested types can be 'protected internal' { result.Append("protected "); } if (mrType.IsPrivate) { result.Append("private "); } var classKind = ""; if (mrType.IsStruct) { classKind = "struct"; } else if (mrType.IsClass) { classKind = "class"; } else if (mrType.IsInterface) { classKind = "interface"; } else if (mrType.IsEnum) { classKind = "enum"; } else { Assert.IsTrue(false); } result.Append($"{classKind} {mrType.GetPrettyFullName()}"); // Write the base type (if this type has one) if (mrType.GetBaseType() != null) { result.Append($" : {mrType.GetBaseType().GetPrettyFullName()}"); } if (mrType.IsNestedType) { result.Append(" (nested)"); } // Write the standard attributes for this type result.AppendLine(); result.AppendLine($" {mrType.Attributes.ToString()}"); // Write custom attributes on this type var customAttributes = mrType.GetCustomAttributes(); foreach (var customAttribute in customAttributes) { customAttribute.GetNameAndNamespace(out var name, out var ns); customAttribute.GetArguments(out var fixedArguments, out var namedArguments); if (fixedArguments.IsEmpty && namedArguments.IsEmpty) { result.AppendLine($" [{name}]"); } else { var allArguments = fixedArguments .Select(fa => $"{fa.Item2.ToString()}") .Union(namedArguments.Select(na => $"{na.Item1}={na.Item2}")); result.AppendLine($" [{name}({string.Join(", ", allArguments)})]"); } } // Write interfaces implemented by this type var interfaces = mrType.GetInterfaces(publicishOnly); foreach (var iface in interfaces) { result.AppendLine($" {iface.GetPrettyFullName()}"); } var nestedTypes = mrType.GetNestedTypes(); foreach (var nestedType in nestedTypes) { result.AppendLine($" nested {nestedType.GetPrettyName()}"); } // Write constructors mrType.GetMethodsAndConstructors(out var methods, out var constructors, publicishOnly); foreach (var constructor in constructors) { var typeName = constructor.DeclaringType.GetPrettyName(); if (mrType.IsNestedType) { typeName = typeName.Split('+').Last(); } result.Append(" "); WriteMethodAccess(constructor, result); result.Append($"{typeName}("); var parameters = constructor.GetParameters(); WriteParameters(parameters, result); result.AppendLine(")"); } // Write properties foreach (var property in mrType.GetProperties(publicishOnly)) { var propertyName = property.GetName(); MrType itemPropertyType = null; if (propertyName == "Item") { itemPropertyType = property.GetItemType(publicishOnly: true); } if (itemPropertyType == null) { result.Append($" {property.GetPropertyType().GetPrettyFullName()} {propertyName} {{ "); if (property.Getter != null) { WriteMethodAccess(property.Getter, result); result.Append("get; "); } if (property.Setter != null) { WriteMethodAccess(property.Setter, result); result.Append($"set; "); } result.AppendLine("}"); } else { result.Append(" "); WriteMethodAccess(property.Getter, result); result.AppendLine($"{property.GetPropertyType().GetPrettyFullName()} this.[{itemPropertyType}]"); } } // Write events var typeEvents = mrType.GetEvents(publicishOnly); foreach (var ev in typeEvents) { result.Append($" "); ev.GetAccessors(out var adder, out var remover); if (adder == null) { result.Append("private "); } else { WriteMethodAccess(adder, result); } result.AppendLine($"{ev.GetEventType().GetPrettyFullName()} {ev.GetName()} {{ add; remove; }}"); } // Write methods foreach (var method in methods) { result.Append(" "); WriteMethodAccess(method, result); result.Append($"{method.ReturnType} {method.GetName()}("); var parameters = method.GetParameters(); WriteParameters(parameters, result); result.AppendLine(")"); } // See later comment where this is used List <string> typeEventNames = null; if (!publicishOnly) { typeEventNames = new List <string>(); foreach (var ev in typeEvents) { typeEventNames.Add(ev.GetName()); } } // Write fields foreach (var field in mrType.GetFields(publicishOnly)) { var name = field.GetName(); // If we're showing private members, we're going to see private events twice; // once as an event and then again as a field. if (!publicishOnly) { if (typeEventNames.Contains(name)) { continue; } } if (mrType.IsEnum) { if (!field.IsSpecialName) // Ignore special value__ field { var value = field.GetConstantValue(out var constantTypeCode); result.AppendLine($" {field.GetName()} = {value},"); } } else { result.AppendLine($" {field.GetFieldType().GetPrettyFullName()} {field.GetName()};"); } } }