Innovenergy_trunk/csharp/Lib/SrcGen/Editor.cs

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());
}
}