blob: e066d24de29e158db84891739876cb489b7c9c5e (
plain)
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
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
using System.Text;
using Microsoft.CodeAnalysis;
namespace ILLink.RoslynAnalyzer
{
public static class ISymbolExtensions
{
/// <summary>
/// Returns true if symbol <see paramref="symbol"/> has an attribute with name <see paramref="attributeName"/>.
/// </summary>
internal static bool HasAttribute (this ISymbol symbol, string attributeName)
{
foreach (var attr in symbol.GetAttributes ())
if (attr.AttributeClass?.Name == attributeName)
return true;
return false;
}
internal static bool TryGetAttribute (this ISymbol member, string attributeName, [NotNullWhen (returnValue: true)] out AttributeData? attribute)
{
attribute = null;
foreach (var attr in member.GetAttributes ()) {
if (attr.AttributeClass is { } attrClass && attrClass.HasName (attributeName)) {
attribute = attr;
return true;
}
}
return false;
}
internal static bool TryGetOverriddenMember (this ISymbol? symbol, [NotNullWhen (returnValue: true)] out ISymbol? overridenMember)
{
overridenMember = symbol switch {
IMethodSymbol method => method.OverriddenMethod,
IPropertySymbol property => property.OverriddenProperty,
IEventSymbol @event => @event.OverriddenEvent,
_ => null,
};
return overridenMember != null;
}
public static string GetDisplayName (this ISymbol symbol)
{
var sb = new StringBuilder ();
switch (symbol) {
case IFieldSymbol fieldSymbol:
sb.Append (fieldSymbol.Type);
sb.Append (" ");
sb.Append (fieldSymbol.ContainingSymbol.ToDisplayString ());
sb.Append ("::");
sb.Append (fieldSymbol.MetadataName);
break;
case IParameterSymbol parameterSymbol:
sb.Append (parameterSymbol.Name);
break;
default:
sb.Append (symbol.ToDisplayString ());
break;
}
return sb.ToString ();
}
public static bool IsInterface (this ISymbol symbol)
{
if (symbol is not INamedTypeSymbol namedTypeSymbol)
return false;
var typeSymbol = namedTypeSymbol as ITypeSymbol;
return typeSymbol.TypeKind == TypeKind.Interface;
}
public static bool IsSubclassOf (this ISymbol symbol, string ns, string type)
{
if (symbol is not ITypeSymbol typeSymbol)
return false;
while (typeSymbol != null) {
if (typeSymbol.ContainingNamespace.Name == ns &&
typeSymbol.ContainingType.Name == type)
return true;
typeSymbol = typeSymbol.ContainingType;
}
return false;
}
}
}
|