-
Notifications
You must be signed in to change notification settings - Fork 4.1k
/
MetadataNameHelpers.cs
124 lines (99 loc) · 3.83 KB
/
MetadataNameHelpers.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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel
{
internal static class MetadataNameHelpers
{
private static void AppendNamespace(INamespaceSymbol namespaceSymbol, StringBuilder builder)
=> builder.Append(namespaceSymbol.Name);
private static void AppendNamedType(INamedTypeSymbol namedTypeSymbol, StringBuilder builder)
{
builder.Append(namedTypeSymbol.Name);
if (namedTypeSymbol.Arity > 0)
{
var typeArguments = namedTypeSymbol.TypeArguments;
builder.Append('`');
builder.Append(typeArguments.Length);
// Append generic arguments
builder.Append('[');
for (var i = 0; i < typeArguments.Length; i++)
{
if (i > 0)
{
builder.Append(',');
}
builder.Append(GetMetadataName(typeArguments[i]));
}
builder.Append(']');
}
}
private static void AppendArrayType(IArrayTypeSymbol symbol, StringBuilder builder)
{
builder.Append(GetMetadataName(symbol.ElementType));
builder.Append('[');
builder.Append(',', symbol.Rank - 1);
builder.Append(']');
}
private static void AppendPointerType(IPointerTypeSymbol symbol, StringBuilder builder)
{
builder.Append(GetMetadataName(symbol.PointedAtType));
builder.Append('*');
}
public static string GetMetadataName(ITypeSymbol typeSymbol)
{
if (typeSymbol.Kind == SymbolKind.TypeParameter)
{
throw new ArgumentException("Type parameters are not suppported", nameof(typeSymbol));
}
using var _ = ArrayBuilder<ISymbol>.GetInstance(out var parts);
ISymbol symbol = typeSymbol;
while (symbol != null)
{
parts.Push(symbol);
symbol = symbol.ContainingSymbol;
}
var builder = new StringBuilder();
while (parts.TryPop(out symbol))
{
if (builder.Length > 0)
{
if (symbol.ContainingSymbol is ITypeSymbol)
{
builder.Append('+');
}
else
{
builder.Append('.');
}
}
switch (symbol.Kind)
{
case SymbolKind.Namespace:
var namespaceSymbol = (INamespaceSymbol)symbol;
if (!namespaceSymbol.IsGlobalNamespace)
{
AppendNamespace(namespaceSymbol, builder);
}
break;
case SymbolKind.NamedType:
AppendNamedType((INamedTypeSymbol)symbol, builder);
break;
case SymbolKind.ArrayType:
AppendArrayType((IArrayTypeSymbol)symbol, builder);
break;
case SymbolKind.PointerType:
AppendPointerType((IPointerTypeSymbol)symbol, builder);
break;
}
}
return builder.ToString();
}
}
}