-
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathObservableAsPropertyGenerator{FromObservable}.cs
More file actions
70 lines (59 loc) · 2.92 KB
/
ObservableAsPropertyGenerator{FromObservable}.cs
File metadata and controls
70 lines (59 loc) · 2.92 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
// Copyright (c) 2025 ReactiveUI and contributors. All rights reserved.
// Licensed to the ReactiveUI and contributors under one or more agreements.
// The ReactiveUI and contributors licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using ReactiveUI.SourceGenerators.Helpers;
namespace ReactiveUI.SourceGenerators;
/// <summary>
/// A source generator for generating reactive properties.
/// </summary>
public sealed partial class ObservableAsPropertyGenerator
{
private static void RunObservableAsPropertyFromObservable(in IncrementalGeneratorInitializationContext context)
{
// Gather info for all annotated command methods (starting from method declarations with at least one attribute)
var methodInfo =
context.SyntaxProvider
.ForAttributeWithMetadataName(
AttributeDefinitions.ObservableAsPropertyAttributeType,
static (node, _) => node is MethodDeclarationSyntax or PropertyDeclarationSyntax { Parent: ClassDeclarationSyntax or RecordDeclarationSyntax, AttributeLists.Count: > 0 },
static (context, token) => GetObservableInfo(context, token))
.Where(x => x != null)
.Select((x, _) => x!)
.Collect();
// Generate the requested properties and methods
context.RegisterSourceOutput(methodInfo, static (context, input) =>
{
foreach (var diagnostic in input.SelectMany(static x => x.Errors))
{
// Output the diagnostics
context.ReportDiagnostic(diagnostic.ToDiagnostic());
}
// Gather all the properties that are valid and group them by the target information.
var groupedPropertyInfo = input
.Where(static x => x.Value != null)
.Select(static x => x.Value!).GroupBy(
static info => (info.TargetInfo.FileHintName, info.TargetInfo.TargetName, info.TargetInfo.TargetNamespace, info.TargetInfo.TargetVisibility, info.TargetInfo.TargetType),
static info => info)
.ToImmutableArray();
if (groupedPropertyInfo.Length == 0)
{
return;
}
foreach (var grouping in groupedPropertyInfo)
{
var items = grouping.ToImmutableArray();
if (items.Length == 0)
{
continue;
}
var source = GenerateObservableSource(grouping.Key.TargetName, grouping.Key.TargetNamespace, grouping.Key.TargetVisibility, grouping.Key.TargetType, [.. grouping]);
context.AddSource($"{grouping.Key.FileHintName}.ObservableAsPropertyFromObservable.g.cs", source);
}
});
}
}