/
SyntaxValueProvider.cs
58 lines (52 loc) · 2.79 KB
/
SyntaxValueProvider.cs
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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// Allows a user to create Syntax based input nodes for incremental generation
/// </summary>
public readonly struct SyntaxValueProvider
{
private readonly ArrayBuilder<ISyntaxInputNode> _inputNodes;
private readonly Action<IIncrementalGeneratorOutputNode> _registerOutput;
internal SyntaxValueProvider(ArrayBuilder<ISyntaxInputNode> inputNodes, Action<IIncrementalGeneratorOutputNode> registerOutput)
{
_inputNodes = inputNodes;
_registerOutput = registerOutput;
}
/// <summary>
/// Creates an <see cref="IncrementalValueProvider{T}"/> that can provide a transform over <see cref="SyntaxNode"/>s
/// </summary>
/// <typeparam name="T">The type of the value the syntax node is transformed into</typeparam>
/// <param name="predicate">A function that determines if the given <see cref="SyntaxNode"/> should be transformed</param>
/// <param name="transform">A function that performs the transform, when <paramref name="predicate"/>returns <c>true</c> for a given node</param>
/// <returns>An <see cref="IncrementalValueProvider{T}"/> that provides the results of the transformation</returns>
public IncrementalValuesProvider<T> CreateSyntaxProvider<T>(Func<SyntaxNode, CancellationToken, bool> predicate, Func<GeneratorSyntaxContext, CancellationToken, T> transform)
{
// registration of the input is deferred until we know the node is used
return new IncrementalValuesProvider<T>(new SyntaxInputNode<T>(predicate.WrapUserFunction(), transform.WrapUserFunction(), RegisterOutputAndDeferredInput));
}
/// <summary>
/// Creates a syntax receiver input node. Only used for back compat in <see cref="SourceGeneratorAdaptor"/>
/// </summary>
internal IncrementalValueProvider<ISyntaxContextReceiver?> CreateSyntaxReceiverProvider(SyntaxContextReceiverCreator creator)
{
var node = new SyntaxReceiverInputNode(creator, _registerOutput);
_inputNodes.Add(node);
return new IncrementalValueProvider<ISyntaxContextReceiver?>(node);
}
private void RegisterOutputAndDeferredInput(ISyntaxInputNode node, IIncrementalGeneratorOutputNode output)
{
_registerOutput(output);
if (!_inputNodes.Contains(node))
{
_inputNodes.Add(node);
}
}
}
}