File tree Expand file tree Collapse file tree 3 files changed +43
-6
lines changed Expand file tree Collapse file tree 3 files changed +43
-6
lines changed Original file line number Diff line number Diff line change 54
54
<Compile Include =" $(MSBuildThisFileDirectory)Extensions\INamedTypeSymbolExtensions.cs" />
55
55
<Compile Include =" $(MSBuildThisFileDirectory)Extensions\IncrementalGeneratorInitializationContextExtensions.cs" />
56
56
<Compile Include =" $(MSBuildThisFileDirectory)Extensions\IncrementalValuesProviderExtensions.cs" />
57
+ <Compile Include =" $(MSBuildThisFileDirectory)Extensions\SymbolInfoExtensions.cs" />
57
58
<Compile Include =" $(MSBuildThisFileDirectory)Extensions\ISymbolExtensions.cs" />
58
59
<Compile Include =" $(MSBuildThisFileDirectory)Extensions\SourceProductionContextExtensions.cs" />
59
60
<Compile Include =" $(MSBuildThisFileDirectory)Extensions\ITypeSymbolExtensions.cs" />
Original file line number Diff line number Diff line change @@ -214,12 +214,7 @@ public static bool TryGetInfo(
214
214
// There is no need to validate anything here: the attribute will be forwarded as is, and then Roslyn will validate on the
215
215
// generated property. Users will get the same validation they'd have had directly over the field. The only drawback is the
216
216
// lack of IntelliSense when constructing attributes over the field, but this is the best we can do from this end anyway.
217
- SymbolInfo attributeSymbolInfo = semanticModel . GetSymbolInfo ( attribute , token ) ;
218
-
219
- // Check if the attribute type can be resolved, and emit a diagnostic if that is not the case. This happens if eg. the
220
- // attribute type is spelled incorrectly, or if a user is missing the using directive for the attribute type being used.
221
- if ( ( attributeSymbolInfo . Symbol ?? attributeSymbolInfo . CandidateSymbols . SingleOrDefault ( ) ) is not ISymbol attributeSymbol ||
222
- ( attributeSymbol as INamedTypeSymbol ?? attributeSymbol . ContainingType ) is not INamedTypeSymbol attributeTypeSymbol )
217
+ if ( ! semanticModel . GetSymbolInfo ( attribute , token ) . TryGetAttributeTypeSymbol ( out INamedTypeSymbol ? attributeTypeSymbol ) )
223
218
{
224
219
builder . Add (
225
220
InvalidPropertyTargetedAttributeOnObservablePropertyField ,
Original file line number Diff line number Diff line change
1
+ // Licensed to the .NET Foundation under one or more agreements.
2
+ // The .NET Foundation licenses this file to you under the MIT license.
3
+ // See the LICENSE file in the project root for more information.
4
+
5
+ using System . Diagnostics . CodeAnalysis ;
6
+ using System . Linq ;
7
+ using Microsoft . CodeAnalysis ;
8
+
9
+ namespace CommunityToolkit . Mvvm . SourceGenerators . Extensions ;
10
+
11
+ /// <summary>
12
+ /// Extension methods for the <see cref="SymbolInfo"/> type.
13
+ /// </summary>
14
+ internal static class SymbolInfoExtensions
15
+ {
16
+ /// <summary>
17
+ /// Tries to get the resolved attribute type symbol from a given <see cref="SymbolInfo"/> value.
18
+ /// </summary>
19
+ /// <param name="symbolInfo">The <see cref="SymbolInfo"/> value to check.</param>
20
+ /// <param name="typeSymbol">The resulting attribute type symbol, if correctly resolved.</param>
21
+ /// <returns>Whether <paramref name="symbolInfo"/> is resolved to a symbol.</returns>
22
+ /// <remarks>
23
+ /// This can be used to ensure users haven't eg. spelled names incorrecty or missed a using directive. Normally, code would just
24
+ /// not compile if that was the case, but that doesn't apply for attributes using invalid targets. In that case, Roslyn will ignore
25
+ /// any errors, meaning the generator has to validate the type symbols are correctly resolved on its own.
26
+ /// </remarks>
27
+ public static bool TryGetAttributeTypeSymbol ( this SymbolInfo symbolInfo , [ NotNullWhen ( true ) ] out INamedTypeSymbol ? typeSymbol )
28
+ {
29
+ if ( ( symbolInfo . Symbol ?? symbolInfo . CandidateSymbols . SingleOrDefault ( ) ) is not ISymbol attributeSymbol ||
30
+ ( attributeSymbol as INamedTypeSymbol ?? attributeSymbol . ContainingType ) is not INamedTypeSymbol resultingSymbol )
31
+ {
32
+ typeSymbol = null ;
33
+
34
+ return false ;
35
+ }
36
+
37
+ typeSymbol = resultingSymbol ;
38
+
39
+ return true ;
40
+ }
41
+ }
You can’t perform that action at this time.
0 commit comments