82 lines
2.2 KiB
C#
82 lines
2.2 KiB
C#
|
using Microsoft.CodeAnalysis;
|
||
|
|
||
|
namespace InnovEnergy.Lib.SrcGen;
|
||
|
|
||
|
public readonly ref struct Rewriter<TRoot, TNode> where TRoot : SyntaxNode where TNode : SyntaxNode
|
||
|
{
|
||
|
internal readonly TRoot Root;
|
||
|
internal readonly IEnumerable<TNode> Descendants;
|
||
|
|
||
|
internal Rewriter(TRoot root, IEnumerable<TNode> descendants)
|
||
|
{
|
||
|
Root = root;
|
||
|
Descendants = descendants;
|
||
|
}
|
||
|
|
||
|
public Rewriter<TRoot, TNode> Where(Func<TNode, Boolean> predicate)
|
||
|
{
|
||
|
return new Rewriter<TRoot, TNode>(Root, Descendants.Where(predicate));
|
||
|
}
|
||
|
|
||
|
public Rewriter<TRoot, T> OfType<T>() where T : TNode
|
||
|
{
|
||
|
return new Rewriter<TRoot, T>(Root, Descendants.OfType<T>());
|
||
|
}
|
||
|
|
||
|
public Rewriter<TRoot, TNode> HasAncestor<T>() where T : SyntaxNode
|
||
|
{
|
||
|
return new Rewriter<TRoot, TNode>(Root, Descendants.Where(d => d.Ancestors().OfType<T>().Any()));
|
||
|
}
|
||
|
|
||
|
public Rewriter<TRoot, TNode> HasParent<T>() where T : SyntaxNode
|
||
|
{
|
||
|
return new Rewriter<TRoot, TNode>(Root, Descendants.Where(d => d.Parent is T));
|
||
|
}
|
||
|
|
||
|
public Rewriter<TRoot, TNode> SelectNodes(Func<TNode, IEnumerable<TNode>> nodes)
|
||
|
{
|
||
|
return new Rewriter<TRoot, TNode>(Root, Descendants.SelectMany(nodes));
|
||
|
}
|
||
|
|
||
|
public Rewriter<TRoot, T> SelectNode<T>(Func<TNode, T> node) where T: SyntaxNode
|
||
|
{
|
||
|
return new Rewriter<TRoot, T>(Root, Descendants.Select(node));
|
||
|
}
|
||
|
|
||
|
public Rewriter<TRoot, T> GetAncestor<T>() where T : SyntaxNode
|
||
|
{
|
||
|
return SelectNode(n => n.Ancestors().OfType<T>().First());
|
||
|
}
|
||
|
|
||
|
public TRoot Replace(SyntaxNode syntaxNode)
|
||
|
{
|
||
|
return Root.ReplaceNodes(Descendants, (_, _) => syntaxNode);
|
||
|
}
|
||
|
|
||
|
public TRoot Replace(Func<TNode, SyntaxNode> map)
|
||
|
{
|
||
|
return Root.ReplaceNodes(Descendants, (_, n) => map(n));
|
||
|
}
|
||
|
|
||
|
public TRoot Remove() => Remove(SyntaxRemoveOptions.KeepNoTrivia);
|
||
|
|
||
|
public TRoot Remove(SyntaxRemoveOptions options) => Root.RemoveNodes(Descendants, options)!;
|
||
|
}
|
||
|
|
||
|
public static class Rewrite
|
||
|
{
|
||
|
public static Rewriter<R, SyntaxNode> EditNodes<R>(this R root) where R : SyntaxNode
|
||
|
{
|
||
|
return new Rewriter<R, SyntaxNode>(root, root.DescendantNodes());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|