forked from CommunityToolkit/dotnet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathITypeSymbolExtensions.cs
More file actions
112 lines (98 loc) · 4.54 KB
/
Copy pathITypeSymbolExtensions.cs
File metadata and controls
112 lines (98 loc) · 4.54 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
// 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.
using System;
using System.Linq;
using Microsoft.CodeAnalysis;
namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions;
/// <summary>
/// Extension methods for the <see cref="ITypeSymbol"/> type.
/// </summary>
internal static class ITypeSymbolExtensions
{
/// <summary>
/// Checks whether or not a given <see cref="ITypeSymbol"/> inherits from a specified type.
/// </summary>
/// <param name="typeSymbol">The target <see cref="ITypeSymbol"/> instance to check.</param>
/// <param name="name">The full name of the type to check for inheritance.</param>
/// <returns>Whether or not <paramref name="typeSymbol"/> inherits from <paramref name="name"/>.</returns>
public static bool InheritsFromFullyQualifiedName(this ITypeSymbol typeSymbol, string name)
{
INamedTypeSymbol? baseType = typeSymbol.BaseType;
while (baseType != null)
{
if (baseType.HasFullyQualifiedName(name))
{
return true;
}
baseType = baseType.BaseType;
}
return false;
}
/// <summary>
/// Checks whether or not a given <see cref="ITypeSymbol"/> implements an interface with a specified name.
/// </summary>
/// <param name="typeSymbol">The target <see cref="ITypeSymbol"/> instance to check.</param>
/// <param name="name">The full name of the type to check for interface implementation.</param>
/// <returns>Whether or not <paramref name="typeSymbol"/> has an interface with the specified name.</returns>
public static bool HasInterfaceWithFullyQualifiedName(this ITypeSymbol typeSymbol, string name)
{
foreach (INamedTypeSymbol interfaceType in typeSymbol.AllInterfaces)
{
if (interfaceType.HasFullyQualifiedName(name))
{
return true;
}
}
return false;
}
/// <summary>
/// Checks whether or not a given <see cref="ITypeSymbol"/> has or inherits a specified attribute.
/// </summary>
/// <param name="typeSymbol">The target <see cref="ITypeSymbol"/> instance to check.</param>
/// <param name="predicate">The predicate used to match available attributes.</param>
/// <returns>Whether or not <paramref name="typeSymbol"/> has an attribute matching <paramref name="predicate"/>.</returns>
public static bool HasOrInheritsAttribute(this ITypeSymbol typeSymbol, Func<AttributeData, bool> predicate)
{
for (ITypeSymbol? currentType = typeSymbol; currentType is not null; currentType = currentType.BaseType)
{
if (currentType.GetAttributes().Any(predicate))
{
return true;
}
}
return false;
}
/// <summary>
/// Checks whether or not a given <see cref="ITypeSymbol"/> has or inherits a specified attribute.
/// </summary>
/// <param name="typeSymbol">The target <see cref="ITypeSymbol"/> instance to check.</param>
/// <param name="name">The name of the attribute to look for.</param>
/// <returns>Whether or not <paramref name="typeSymbol"/> has an attribute with the specified type name.</returns>
public static bool HasOrInheritsAttributeWithFullyQualifiedName(this ITypeSymbol typeSymbol, string name)
{
for (ITypeSymbol? currentType = typeSymbol; currentType is not null; currentType = currentType.BaseType)
{
if (currentType.HasAttributeWithFullyQualifiedName(name))
{
return true;
}
}
return false;
}
/// <summary>
/// Checks whether or not a given <see cref="ITypeSymbol"/> inherits a specified attribute.
/// If the type has no base type, this method will automatically handle that and return <see langword="false"/>.
/// </summary>
/// <param name="typeSymbol">The target <see cref="ITypeSymbol"/> instance to check.</param>
/// <param name="name">The name of the attribute to look for.</param>
/// <returns>Whether or not <paramref name="typeSymbol"/> has an attribute with the specified type name.</returns>
public static bool InheritsAttributeWithFullyQualifiedName(this ITypeSymbol typeSymbol, string name)
{
if (typeSymbol.BaseType is INamedTypeSymbol baseTypeSymbol)
{
return HasOrInheritsAttributeWithFullyQualifiedName(baseTypeSymbol, name);
}
return false;
}
}