|
2 | 2 | // The .NET Foundation licenses this file to you under the MIT license.
|
3 | 3 | // See the LICENSE file in the project root for more information.
|
4 | 4 |
|
5 |
| -using System.Collections.Generic; |
6 |
| -using System.Diagnostics.CodeAnalysis; |
| 5 | +using System.Collections.Immutable; |
7 | 6 | using System.Linq;
|
| 7 | +using CommunityToolkit.Mvvm.SourceGenerators.Diagnostics; |
| 8 | +using CommunityToolkit.Mvvm.SourceGenerators.Extensions; |
| 9 | +using CommunityToolkit.Mvvm.SourceGenerators.Input.Models; |
8 | 10 | using Microsoft.CodeAnalysis;
|
9 | 11 | using Microsoft.CodeAnalysis.CSharp.Syntax;
|
10 |
| -using CommunityToolkit.Mvvm.SourceGenerators.Extensions; |
11 | 12 | using static CommunityToolkit.Mvvm.SourceGenerators.Diagnostics.DiagnosticDescriptors;
|
12 | 13 |
|
13 | 14 | namespace CommunityToolkit.Mvvm.SourceGenerators;
|
14 | 15 |
|
15 | 16 | /// <summary>
|
16 | 17 | /// A source generator for the <c>INotifyPropertyChangedAttribute</c> type.
|
17 | 18 | /// </summary>
|
18 |
| -[Generator] |
19 |
| -public sealed class INotifyPropertyChangedGenerator : TransitiveMembersGenerator |
| 19 | +[Generator(LanguageNames.CSharp)] |
| 20 | +public sealed class INotifyPropertyChangedGenerator : TransitiveMembersGenerator2<INotifyPropertyChangedInfo> |
20 | 21 | {
|
21 | 22 | /// <summary>
|
22 | 23 | /// Initializes a new instance of the <see cref="INotifyPropertyChangedGenerator"/> class.
|
23 | 24 | /// </summary>
|
24 | 25 | public INotifyPropertyChangedGenerator()
|
25 |
| - : base("CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute") |
| 26 | + : base("global::CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute") |
26 | 27 | {
|
27 | 28 | }
|
28 | 29 |
|
29 | 30 | /// <inheritdoc/>
|
30 |
| - protected override DiagnosticDescriptor TargetTypeErrorDescriptor => INotifyPropertyChangedGeneratorError; |
| 31 | + protected override INotifyPropertyChangedInfo GetInfo(AttributeData attributeData) |
| 32 | + { |
| 33 | + if (attributeData.TryGetNamedArgument("IncludeAdditionalHelperMethods", out bool includeAdditionalHelperMethods)) |
| 34 | + { |
| 35 | + return new(includeAdditionalHelperMethods); |
| 36 | + } |
| 37 | + |
| 38 | + return new(false); |
| 39 | + } |
31 | 40 |
|
32 | 41 | /// <inheritdoc/>
|
33 | 42 | protected override bool ValidateTargetType(
|
34 |
| - GeneratorExecutionContext context, |
35 |
| - AttributeData attributeData, |
36 |
| - ClassDeclarationSyntax classDeclaration, |
37 |
| - INamedTypeSymbol classDeclarationSymbol, |
38 |
| - [NotNullWhen(false)] out DiagnosticDescriptor? descriptor) |
| 43 | + INamedTypeSymbol typeSymbol, |
| 44 | + INotifyPropertyChangedInfo info, |
| 45 | + out ImmutableArray<Diagnostic> diagnostics) |
39 | 46 | {
|
40 |
| - INamedTypeSymbol iNotifyPropertyChangedSymbol = context.Compilation.GetTypeByMetadataName("System.ComponentModel.INotifyPropertyChanged")!; |
| 47 | + ImmutableArray<Diagnostic>.Builder builder = ImmutableArray.CreateBuilder<Diagnostic>(); |
41 | 48 |
|
42 | 49 | // Check if the type already implements INotifyPropertyChanged
|
43 |
| - if (classDeclarationSymbol.AllInterfaces.Any(i => SymbolEqualityComparer.Default.Equals(i, iNotifyPropertyChangedSymbol))) |
| 50 | + if (typeSymbol.AllInterfaces.Any(i => i.HasFullyQualifiedName("global::System.ComponentModel.INotifyPropertyChanged"))) |
44 | 51 | {
|
45 |
| - descriptor = DuplicateINotifyPropertyChangedInterfaceForINotifyPropertyChangedAttributeError; |
| 52 | + builder.Add(DuplicateINotifyPropertyChangedInterfaceForINotifyPropertyChangedAttributeError, typeSymbol, typeSymbol); |
| 53 | + |
| 54 | + diagnostics = builder.ToImmutable(); |
46 | 55 |
|
47 | 56 | return false;
|
48 | 57 | }
|
49 | 58 |
|
50 |
| - descriptor = null; |
| 59 | + diagnostics = builder.ToImmutable(); |
51 | 60 |
|
52 | 61 | return true;
|
53 | 62 | }
|
54 | 63 |
|
55 | 64 | /// <inheritdoc/>
|
56 |
| - protected override IEnumerable<MemberDeclarationSyntax> FilterDeclaredMembers( |
57 |
| - GeneratorExecutionContext context, |
58 |
| - AttributeData attributeData, |
59 |
| - ClassDeclarationSyntax classDeclaration, |
60 |
| - INamedTypeSymbol classDeclarationSymbol, |
61 |
| - ClassDeclarationSyntax sourceDeclaration) |
| 65 | + protected override ImmutableArray<MemberDeclarationSyntax> FilterDeclaredMembers(INotifyPropertyChangedInfo info, ClassDeclarationSyntax classDeclaration) |
62 | 66 | {
|
63 | 67 | // If requested, only include the event and the basic methods to raise it, but not the additional helpers
|
64 |
| - if (attributeData.HasNamedArgument("IncludeAdditionalHelperMethods", false)) |
| 68 | + if (!info.IncludeAdditionalHelperMethods) |
65 | 69 | {
|
66 |
| - return sourceDeclaration.Members.Where(static member => |
67 |
| - { |
68 |
| - return member |
| 70 | + return classDeclaration.Members.Where( |
| 71 | + static member => member |
69 | 72 | is EventFieldDeclarationSyntax
|
70 |
| - or MethodDeclarationSyntax { Identifier: { ValueText: "OnPropertyChanged" } }; |
71 |
| - }); |
| 73 | + or MethodDeclarationSyntax { Identifier.ValueText: "OnPropertyChanged" }).ToImmutableArray(); |
72 | 74 | }
|
73 | 75 |
|
74 |
| - return sourceDeclaration.Members; |
| 76 | + return classDeclaration.Members.ToImmutableArray(); |
75 | 77 | }
|
76 | 78 | }
|
0 commit comments