forked from efcore/EFCore.VisualBasic
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVBTypeExtensions.vb
More file actions
130 lines (106 loc) · 4.41 KB
/
Copy pathVBTypeExtensions.vb
File metadata and controls
130 lines (106 loc) · 4.41 KB
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
Imports System.Runtime.CompilerServices
Imports System.Text
Friend Module VBTypeExtensions
<Extension()>
Public Function ShortDisplayName(type As Type) As String
Return type.DisplayName(fullName:=False)
End Function
<Extension()>
Public Function DisplayName(type As Type,
Optional fullName As Boolean = True,
Optional compilable As Boolean = False) As String
Dim stringBuilder As New StringBuilder()
ProcessType(stringBuilder, type, fullName, compilable)
Return stringBuilder.ToString()
End Function
Private Sub ProcessType(builder As StringBuilder, type As Type, fullName As Boolean, compilable As Boolean)
Dim builtInName As String = Nothing
If type.IsGenericType Then
Dim genericArguments = type.GetGenericArguments()
ProcessGenericType(builder, type, genericArguments, genericArguments.Length, fullName, compilable)
ElseIf type.IsArray Then
ProcessArrayType(builder, type, fullName, compilable)
ElseIf _builtInTypeNames.TryGetValue(type, builtInName) Then
builder.Append(builtInName)
ElseIf Not type.IsGenericParameter Then
If compilable Then
If type.IsNested Then
ProcessType(builder, type.DeclaringType, fullName, compilable)
builder.Append("."c)
ElseIf fullName Then
builder.Append(type.Namespace).Append("."c)
End If
Dim typeName = type.Name
If IsVisualBasicKeyword(typeName) Then
typeName = $"[{typeName}]"
End If
builder.Append(typeName)
Else
builder.Append(If(fullName, type.FullName, type.Name))
End If
End If
End Sub
Private Sub ProcessArrayType(builder As StringBuilder, type As Type, fullName As Boolean, compilable As Boolean)
Dim innerType = type
While innerType.IsArray
innerType = innerType.GetElementType()
End While
ProcessType(builder, innerType, fullName, compilable)
While type.IsArray
builder.
Append("("c).
Append(","c, type.GetArrayRank() - 1).
Append(")"c)
type = type.GetElementType()
End While
End Sub
Private Sub ProcessGenericType(builder As StringBuilder,
type As Type, genericArguments As Type(),
length As Integer,
fullName As Boolean,
compilable As Boolean)
If type.IsConstructedGenericType AndAlso type.GetGenericTypeDefinition() = GetType(Nullable(Of)) Then
ProcessType(builder, type.UnwrapNullableType(), fullName, compilable)
builder.Append("?"c)
Return
End If
Dim offset = If(type.IsNested, type.DeclaringType.GetGenericArguments().Length, 0)
If compilable Then
If type.IsNested Then
ProcessType(builder, type.DeclaringType, fullName, compilable)
builder.Append("."c)
ElseIf fullName Then
builder.Append(type.Namespace).
Append("."c)
End If
Else
If fullName Then
If type.IsNested Then
ProcessGenericType(builder, type.DeclaringType, genericArguments, offset, fullName, compilable)
builder.Append("+"c)
Else
builder.Append(type.Namespace).
Append("."c)
End If
End If
End If
Dim genericPartIndex = type.Name.IndexOf("`"c)
If genericPartIndex <= 0 Then
builder.Append(type.Name)
Return
End If
builder.Append(type.Name, 0, genericPartIndex)
builder.Append("(Of ")
For i = offset To length - 1
ProcessType(builder, genericArguments(i), fullName, compilable)
If i + 1 = length Then
Continue For
End If
builder.Append(","c)
If Not genericArguments(i + 1).IsGenericParameter Then
builder.Append(" "c)
End If
Next
builder.Append(")"c)
End Sub
End Module