File tree Expand file tree Collapse file tree 2 files changed +35
-7
lines changed Expand file tree Collapse file tree 2 files changed +35
-7
lines changed 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 Microsoft . CodeAnalysis ;
6+
7+ namespace CommunityToolkit . Mvvm . SourceGenerators . Extensions ;
8+
9+ /// <summary>
10+ /// Extension methods for the <see cref="SyntaxNode"/> type.
11+ /// </summary>
12+ internal static class SyntaxNodeExtensions
13+ {
14+ /// <summary>
15+ /// Checks whether a given <see cref="SyntaxNode"/> represents the first (partial) declaration of a given symbol.
16+ /// </summary>
17+ /// <param name="syntaxNode">The input <see cref="SyntaxNode"/> instance.</param>
18+ /// <param name="symbol">The target <see cref="ISymbol"/> instance to check the syntax declaration for.</param>
19+ /// <returns>Whether <paramref name="syntaxNode"/> is the first (partial) declaration for <paramref name="symbol"/>.</returns>
20+ /// <remarks>
21+ /// This extension can be used to avoid accidentally generating repeated members for types that have multiple partial declarations.
22+ /// In order to keep this check efficient and without the need to collect all items and build some sort of hashset from them to
23+ /// remove duplicates, each syntax node is symply compared against the available declaring syntax references for the target symbol.
24+ /// If the syntax node matches the first syntax reference for the symbol, it is kept, otherwise it is considered a duplicate.
25+ /// </remarks>
26+ public static bool IsFirstSyntaxDeclarationForSymbol ( this SyntaxNode syntaxNode , ISymbol symbol )
27+ {
28+ return
29+ symbol . DeclaringSyntaxReferences . Length > 0 &&
30+ symbol . DeclaringSyntaxReferences [ 0 ] is SyntaxReference syntaxReference &&
31+ syntaxReference . SyntaxTree == syntaxNode . SyntaxTree &&
32+ syntaxReference . Span == syntaxNode . Span ;
33+ }
34+ }
Original file line number Diff line number Diff line change 44
55using System . Collections . Immutable ;
66using System . Linq ;
7- using System . Text ;
87using CommunityToolkit . Mvvm . SourceGenerators . Extensions ;
98using CommunityToolkit . Mvvm . SourceGenerators . Input . Models ;
109using Microsoft . CodeAnalysis ;
1110using Microsoft . CodeAnalysis . CSharp ;
1211using Microsoft . CodeAnalysis . CSharp . Syntax ;
13- using Microsoft . CodeAnalysis . Text ;
1412
1513namespace CommunityToolkit . Mvvm . SourceGenerators ;
1614
@@ -32,11 +30,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
3230 . CreateSyntaxProvider (
3331 static ( node , _ ) => node is ClassDeclarationSyntax ,
3432 static ( context , _ ) => ( context . Node , Symbol : ( INamedTypeSymbol ) context . SemanticModel . GetDeclaredSymbol ( context . Node ) ! ) )
35- . Where ( static item =>
36- item . Symbol . DeclaringSyntaxReferences . Length > 0 &&
37- item . Symbol . DeclaringSyntaxReferences [ 0 ] is SyntaxReference syntaxReference &&
38- syntaxReference . SyntaxTree == item . Node . SyntaxTree &&
39- syntaxReference . Span == item . Node . Span )
33+ . Where ( static item => item . Node . IsFirstSyntaxDeclarationForSymbol ( item . Symbol ) )
4034 . Select ( static ( item , _ ) => item . Symbol ) ;
4135
4236 // Get the target IRecipient<TMessage> interfaces and filter out other types
You can’t perform that action at this time.
0 commit comments