-
-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathXmlCommentsIdHelper.cs
144 lines (128 loc) · 5.54 KB
/
XmlCommentsIdHelper.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Swagger.Net.XmlComments
{
public static class XmlCommentsIdHelper
{
public static string GetCommentIdForMethod(this MethodInfo methodInfo)
{
var builder = new StringBuilder("M:");
AppendFullTypeName(methodInfo.DeclaringType, builder);
builder.Append(".");
AppendMethodName(methodInfo, builder);
return builder.ToString();
}
public static string GetCommentId(this Type type)
{
var builder = new StringBuilder("T:");
AppendFullTypeName(type, builder, expandGenericArgs: false);
return builder.ToString();
}
public static string GetCommentId(this PropertyInfo propertyInfo)
{
var builder = new StringBuilder("P:");
AppendFullTypeName(propertyInfo.DeclaringType, builder);
builder.Append(".");
builder.Append(propertyInfo.Name);
return builder.ToString();
}
public static string GetCommentId(this FieldInfo fieldInfo)
{
var builder = new StringBuilder("F:");
AppendFullTypeName(fieldInfo.DeclaringType, builder);
builder.Append(".");
builder.Append(fieldInfo.Name);
return builder.ToString();
}
private static void AppendFullTypeName(Type type, StringBuilder builder, bool expandGenericArgs = false, IDictionary<string, int> genericParametersPositions = null)
{
if (type.Namespace != null)
{
builder.Append(type.Namespace);
builder.Append(".");
}
AppendTypeName(type, builder, expandGenericArgs, genericParametersPositions);
}
public static string GetNameWithoutGenericArity(Type t)
{
string name = t.Name;
int index = name.IndexOf('`');
return index == -1 ? name : name.Substring(0, index);
}
private static void AppendTypeName(Type type, StringBuilder builder, bool expandGenericArgs, IDictionary<string, int> genericParametersPositions = null)
{
if (type.IsNested)
{
AppendTypeName(type.DeclaringType, builder, genericParametersPositions != null, GetTypeParameterPositions(type.DeclaringType));
builder.Append(".");
}
if ((type.IsGenericType && expandGenericArgs) || type.IsArray)
{
var nonGenericName = GetNameWithoutGenericArity(type);
builder.Append(nonGenericName);
if (type.IsEnum)
return;
}
else
builder.Append(type.Name);
if (expandGenericArgs)
ExpandGenericArgsIfAny(type, builder, genericParametersPositions);
if (type.IsArray)
builder.Append("[]");
}
public static void ExpandGenericArgsIfAny(Type type, StringBuilder builder, IDictionary<string, int> genericParametersPositions = null)
{
if (type.IsGenericType)
{
var genericArgs = type.GetGenericArguments();
builder.Append("{");
for (int i = 0; i < genericArgs.Length; i++)
{
if (type.IsEnum || ((type.IsClass || type.IsInterface) && genericArgs[i].FullName == null))
builder.Append($"`{genericParametersPositions[genericArgs[i].Name]}");
else
AppendFullTypeName(genericArgs[i], builder, true, genericParametersPositions);
builder.Append(",");
}
builder.Replace(",", "}", builder.Length - 1, 1);
}
else if (type.IsArray)
ExpandGenericArgsIfAny(type.GetElementType(), builder, genericParametersPositions);
}
private static void AppendMethodName(MethodInfo methodInfo, StringBuilder builder)
{
var methodName = methodInfo.Name;
builder.Append(methodName);
var declaringType = methodInfo.DeclaringType;
if (declaringType.IsGenericType)
{
methodInfo = declaringType.GetGenericTypeDefinition().GetMethod(methodInfo.Name);
}
var parameters = methodInfo.GetParameters();
if (parameters.Length == 0) return;
builder.Append("(");
var genericParametersPositions = GetTypeParameterPositions(declaringType);
foreach (var param in parameters)
{
if (param.ParameterType.IsGenericParameter)
builder.Append($"`{genericParametersPositions[param.ParameterType.Name]}");
else
AppendFullTypeName(param.ParameterType, builder, true, genericParametersPositions);
builder.Append(",");
}
builder.Replace(",", ")", builder.Length - 1, 1);
}
private static IDictionary<string, int> GetTypeParameterPositions(Type type)
{
var result = new Dictionary<string, int>();
if (!type.IsGenericType)
return result;
var genericTypeDefinition = type.GetGenericTypeDefinition();
foreach (var genericArgument in genericTypeDefinition.GetGenericArguments())
result.Add(genericArgument.Name, genericArgument.GenericParameterPosition);
return result;
}
}
}