-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFactory.FlatMembers.cs
73 lines (64 loc) · 3.66 KB
/
Factory.FlatMembers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System.Text.RegularExpressions;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.TypeSystem;
namespace NetAmermaid
{
partial class ClassDiagrammerFactory
{
/// <summary>Wraps a <see cref="CSharpDecompiler"/> method configurable via <see cref="decompilerSettings"/>
/// that can be used to determine whether a member should be hidden.</summary>
private bool IsHidden(IEntity entity) => CSharpDecompiler.MemberIsHidden(entity.ParentModule!.PEFile, entity.MetadataToken, decompilerSettings);
private IField[] GetFields(ITypeDefinition type, IProperty[] properties)
// only display fields that are not backing properties of the same name and type
=> type.GetFields(f => !IsHidden(f) // removes compiler-generated backing fields
/* tries to remove remaining manual backing fields by matching type and name */
&& !properties.Any(p => f.ReturnType.Equals(p.ReturnType)
&& Regex.IsMatch(f.Name, "_?" + p.Name, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.NonBacktracking))).ToArray();
private static IEnumerable<IMethod> GetMethods(ITypeDefinition type) => type.GetMethods(m =>
!m.IsOperator && !m.IsCompilerGenerated()
&& (m.DeclaringType == type // include methods if self-declared
/* but exclude methods declared by object and their overrides, if inherited */
|| !m.DeclaringType.IsObject()
&& (!m.IsOverride || !InheritanceHelper.GetBaseMember(m).DeclaringType.IsObject())));
private string FormatMethod(IMethod method)
{
string parameters = method.Parameters.Select(p => $"{GetName(p.Type)} {p.Name}").Join(", ");
string? modifier = method.IsAbstract ? "*" : method.IsStatic ? "$" : default;
string name = method.Name;
if (method.IsExplicitInterfaceImplementation)
{
IMember member = method.ExplicitlyImplementedInterfaceMembers.Single();
name = GetName(member.DeclaringType) + '.' + member.Name;
}
string? typeArguments = method.TypeArguments.Count == 0 ? null : $"❰{method.TypeArguments.Select(GetName).Join(", ")}❱";
return $"{GetAccessibility(method.Accessibility)}{name}{typeArguments}({parameters}){modifier} {GetName(method.ReturnType)}";
}
private string FormatFlatProperty(IProperty property)
{
char? visibility = GetAccessibility(property.Accessibility);
string? modifier = property.IsAbstract ? "*" : property.IsStatic ? "$" : default;
return $"{visibility}{GetName(property.ReturnType)} {property.Name}{modifier}";
}
private string FormatField(IField field)
{
string? modifier = field.IsAbstract ? "*" : field.IsStatic ? "$" : default;
return $"{GetAccessibility(field.Accessibility)}{GetName(field.ReturnType)} {field.Name}{modifier}";
}
// see https://stackoverflow.com/a/16024302 for accessibility modifier flags
private char? GetAccessibility(Accessibility access)
{
switch (access)
{
case Accessibility.Private: return '-';
case Accessibility.ProtectedAndInternal:
case Accessibility.Internal: return '~';
case Accessibility.Protected:
case Accessibility.ProtectedOrInternal: return '#';
case Accessibility.Public: return '+';
case Accessibility.None:
default: return default;
}
}
}
}