|
4 | 4 |
|
5 | 5 | using System;
|
6 | 6 | using System.Linq;
|
| 7 | +using CommunityToolkit.Mvvm.SourceGenerators.Helpers; |
7 | 8 | using Microsoft.CodeAnalysis;
|
8 | 9 |
|
9 | 10 | namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions;
|
@@ -128,4 +129,82 @@ public static bool InheritsAttributeWithFullyQualifiedName(this ITypeSymbol type
|
128 | 129 |
|
129 | 130 | return false;
|
130 | 131 | }
|
| 132 | + |
| 133 | + /// <summary> |
| 134 | + /// Checks whether or not a given type symbol has a specified fully qualified metadata name. |
| 135 | + /// </summary> |
| 136 | + /// <param name="symbol">The input <see cref="ITypeSymbol"/> instance to check.</param> |
| 137 | + /// <param name="name">The full name to check.</param> |
| 138 | + /// <returns>Whether <paramref name="symbol"/> has a full name equals to <paramref name="name"/>.</returns> |
| 139 | + public static bool HasFullyQualifiedMetadataName(this ITypeSymbol symbol, string name) |
| 140 | + { |
| 141 | + using ImmutableArrayBuilder<char> builder = ImmutableArrayBuilder<char>.Rent(); |
| 142 | + |
| 143 | + symbol.AppendFullyQualifiedMetadataName(in builder); |
| 144 | + |
| 145 | + return builder.WrittenSpan.SequenceEqual(name.AsSpan()); |
| 146 | + } |
| 147 | + |
| 148 | + /// <summary> |
| 149 | + /// Gets the fully qualified metadata name for a given <see cref="ITypeSymbol"/> instance. |
| 150 | + /// </summary> |
| 151 | + /// <param name="symbol">The input <see cref="ITypeSymbol"/> instance.</param> |
| 152 | + /// <returns>The fully qualified metadata name for <paramref name="symbol"/>.</returns> |
| 153 | + public static string GetFullyQualifiedMetadataName(this ITypeSymbol symbol) |
| 154 | + { |
| 155 | + using ImmutableArrayBuilder<char> builder = ImmutableArrayBuilder<char>.Rent(); |
| 156 | + |
| 157 | + symbol.AppendFullyQualifiedMetadataName(in builder); |
| 158 | + |
| 159 | + return builder.ToString(); |
| 160 | + } |
| 161 | + |
| 162 | + /// <summary> |
| 163 | + /// Appends the fully qualified metadata name for a given symbol to a target builder. |
| 164 | + /// </summary> |
| 165 | + /// <param name="symbol">The input <see cref="ITypeSymbol"/> instance.</param> |
| 166 | + /// <param name="builder">The target <see cref="ImmutableArrayBuilder{T}"/> instance.</param> |
| 167 | + public static void AppendFullyQualifiedMetadataName(this ITypeSymbol symbol, in ImmutableArrayBuilder<char> builder) |
| 168 | + { |
| 169 | + static void BuildFrom(ISymbol? symbol, in ImmutableArrayBuilder<char> builder) |
| 170 | + { |
| 171 | + switch (symbol) |
| 172 | + { |
| 173 | + // Namespaces that are nested also append a leading '.' |
| 174 | + case INamespaceSymbol { ContainingNamespace.IsGlobalNamespace: false }: |
| 175 | + BuildFrom(symbol.ContainingNamespace, in builder); |
| 176 | + builder.Add('.'); |
| 177 | + builder.AddRange(symbol.MetadataName.AsSpan()); |
| 178 | + break; |
| 179 | + |
| 180 | + // Other namespaces (ie. the one right before global) skip the leading '.' |
| 181 | + case INamespaceSymbol { IsGlobalNamespace: false }: |
| 182 | + builder.AddRange(symbol.MetadataName.AsSpan()); |
| 183 | + break; |
| 184 | + |
| 185 | + // Types with no namespace just have their metadata name directly written |
| 186 | + case ITypeSymbol { ContainingSymbol: INamespaceSymbol { IsGlobalNamespace: true } }: |
| 187 | + builder.AddRange(symbol.MetadataName.AsSpan()); |
| 188 | + break; |
| 189 | + |
| 190 | + // Types with a containing non-global namespace also append a leading '.' |
| 191 | + case ITypeSymbol { ContainingSymbol: INamespaceSymbol namespaceSymbol }: |
| 192 | + BuildFrom(namespaceSymbol, in builder); |
| 193 | + builder.Add('.'); |
| 194 | + builder.AddRange(symbol.MetadataName.AsSpan()); |
| 195 | + break; |
| 196 | + |
| 197 | + // Nested types append a leading '+' |
| 198 | + case ITypeSymbol { ContainingSymbol: ITypeSymbol typeSymbol }: |
| 199 | + BuildFrom(typeSymbol, in builder); |
| 200 | + builder.Add('+'); |
| 201 | + builder.AddRange(symbol.MetadataName.AsSpan()); |
| 202 | + break; |
| 203 | + default: |
| 204 | + break; |
| 205 | + } |
| 206 | + } |
| 207 | + |
| 208 | + BuildFrom(symbol, in builder); |
| 209 | + } |
131 | 210 | }
|
0 commit comments