Files
2026-08-27 10:56:38 -06:00

515 lines
22 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Syntax;
internal static class SyntaxReplacer
{
private class Replacer<TNode> : CSharpSyntaxRewriter where TNode : SyntaxNode
{
private readonly Func<TNode, TNode, SyntaxNode>? _computeReplacementNode;
private readonly Func<SyntaxToken, SyntaxToken, SyntaxToken>? _computeReplacementToken;
private readonly Func<SyntaxTrivia, SyntaxTrivia, SyntaxTrivia>? _computeReplacementTrivia;
private readonly HashSet<SyntaxNode> _nodeSet;
private readonly HashSet<SyntaxToken> _tokenSet;
private readonly HashSet<SyntaxTrivia> _triviaSet;
private readonly HashSet<TextSpan> _spanSet;
private readonly TextSpan _totalSpan;
private readonly bool _visitIntoStructuredTrivia;
private readonly bool _shouldVisitTrivia;
private static readonly HashSet<SyntaxNode> s_noNodes = new HashSet<SyntaxNode>();
private static readonly HashSet<SyntaxToken> s_noTokens = new HashSet<SyntaxToken>();
private static readonly HashSet<SyntaxTrivia> s_noTrivia = new HashSet<SyntaxTrivia>();
public override bool VisitIntoStructuredTrivia => _visitIntoStructuredTrivia;
public bool HasWork => _nodeSet.Count + _tokenSet.Count + _triviaSet.Count > 0;
public Replacer(IEnumerable<TNode>? nodes, Func<TNode, TNode, SyntaxNode>? computeReplacementNode, IEnumerable<SyntaxToken>? tokens, Func<SyntaxToken, SyntaxToken, SyntaxToken>? computeReplacementToken, IEnumerable<SyntaxTrivia>? trivia, Func<SyntaxTrivia, SyntaxTrivia, SyntaxTrivia>? computeReplacementTrivia)
{
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
_computeReplacementNode = computeReplacementNode;
_computeReplacementToken = computeReplacementToken;
_computeReplacementTrivia = computeReplacementTrivia;
_nodeSet = ((nodes != null) ? new HashSet<SyntaxNode>((IEnumerable<SyntaxNode>)nodes) : s_noNodes);
_tokenSet = ((tokens != null) ? new HashSet<SyntaxToken>(tokens) : s_noTokens);
_triviaSet = ((trivia != null) ? new HashSet<SyntaxTrivia>(trivia) : s_noTrivia);
_spanSet = new HashSet<TextSpan>(_nodeSet.Select((SyntaxNode n) => n.FullSpan).Concat(_tokenSet.Select((SyntaxToken t) => ((SyntaxToken)(ref t)).FullSpan).Concat(_triviaSet.Select((SyntaxTrivia t) => ((SyntaxTrivia)(ref t)).FullSpan))));
_totalSpan = ComputeTotalSpan(_spanSet);
_visitIntoStructuredTrivia = HashSetExtensions.Any<SyntaxNode>(_nodeSet, (Func<SyntaxNode, bool>)((SyntaxNode n) => n.IsPartOfStructuredTrivia())) || HashSetExtensions.Any<SyntaxToken>(_tokenSet, (Func<SyntaxToken, bool>)((SyntaxToken t) => ((SyntaxToken)(ref t)).IsPartOfStructuredTrivia())) || HashSetExtensions.Any<SyntaxTrivia>(_triviaSet, (Func<SyntaxTrivia, bool>)((SyntaxTrivia t) => ((SyntaxTrivia)(ref t)).IsPartOfStructuredTrivia()));
_shouldVisitTrivia = _triviaSet.Count > 0 || _visitIntoStructuredTrivia;
}
private static TextSpan ComputeTotalSpan(IEnumerable<TextSpan> spans)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
bool flag = true;
int num = 0;
int num2 = 0;
foreach (TextSpan span in spans)
{
TextSpan current = span;
if (flag)
{
num = ((TextSpan)(ref current)).Start;
num2 = ((TextSpan)(ref current)).End;
flag = false;
}
else
{
num = Math.Min(num, ((TextSpan)(ref current)).Start);
num2 = Math.Max(num2, ((TextSpan)(ref current)).End);
}
}
return new TextSpan(num, num2 - num);
}
private bool ShouldVisit(TextSpan span)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (!((TextSpan)(ref span)).IntersectsWith(_totalSpan))
{
return false;
}
foreach (TextSpan item in _spanSet)
{
if (((TextSpan)(ref span)).IntersectsWith(item))
{
return true;
}
}
return false;
}
[return: NotNullIfNotNull("node")]
public override SyntaxNode? Visit(SyntaxNode? node)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
SyntaxNode val = node;
if (node != null)
{
if (ShouldVisit(node.FullSpan))
{
val = base.Visit(node);
}
if (_nodeSet.Contains(node) && _computeReplacementNode != null)
{
val = _computeReplacementNode((TNode)(object)node, (TNode)(object)val);
}
}
return val;
}
public override SyntaxToken VisitToken(SyntaxToken token)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
SyntaxToken val = token;
if (_shouldVisitTrivia && ShouldVisit(((SyntaxToken)(ref token)).FullSpan))
{
val = base.VisitToken(token);
}
if (_tokenSet.Contains(token) && _computeReplacementToken != null)
{
val = _computeReplacementToken(token, val);
}
return val;
}
public override SyntaxTrivia VisitListElement(SyntaxTrivia trivia)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
SyntaxTrivia val = trivia;
if (VisitIntoStructuredTrivia && ((SyntaxTrivia)(ref trivia)).HasStructure && ShouldVisit(((SyntaxTrivia)(ref trivia)).FullSpan))
{
val = VisitTrivia(trivia);
}
if (_triviaSet.Contains(trivia) && _computeReplacementTrivia != null)
{
val = _computeReplacementTrivia(trivia, val);
}
return val;
}
}
private enum ListEditKind
{
InsertBefore,
InsertAfter,
Replace
}
private abstract class BaseListEditor : CSharpSyntaxRewriter
{
private readonly TextSpan _elementSpan;
private readonly bool _visitTrivia;
private readonly bool _visitIntoStructuredTrivia;
protected readonly ListEditKind editKind;
public override bool VisitIntoStructuredTrivia => _visitIntoStructuredTrivia;
public BaseListEditor(TextSpan elementSpan, ListEditKind editKind, bool visitTrivia, bool visitIntoStructuredTrivia)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
_elementSpan = elementSpan;
this.editKind = editKind;
_visitTrivia = visitTrivia || visitIntoStructuredTrivia;
_visitIntoStructuredTrivia = visitIntoStructuredTrivia;
}
private bool ShouldVisit(TextSpan span)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
if (((TextSpan)(ref span)).IntersectsWith(_elementSpan))
{
return true;
}
return false;
}
[return: NotNullIfNotNull("node")]
public override SyntaxNode? Visit(SyntaxNode? node)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
SyntaxNode result = node;
if (node != null && ShouldVisit(node.FullSpan))
{
result = base.Visit(node);
}
return result;
}
public override SyntaxToken VisitToken(SyntaxToken token)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
SyntaxToken result = token;
if (_visitTrivia && ShouldVisit(((SyntaxToken)(ref token)).FullSpan))
{
result = base.VisitToken(token);
}
return result;
}
public override SyntaxTrivia VisitListElement(SyntaxTrivia trivia)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
SyntaxTrivia result = trivia;
if (VisitIntoStructuredTrivia && ((SyntaxTrivia)(ref trivia)).HasStructure && ShouldVisit(((SyntaxTrivia)(ref trivia)).FullSpan))
{
result = VisitTrivia(trivia);
}
return result;
}
}
private class NodeListEditor : BaseListEditor
{
private readonly SyntaxNode _originalNode;
private readonly IEnumerable<SyntaxNode> _newNodes;
public NodeListEditor(SyntaxNode originalNode, IEnumerable<SyntaxNode> replacementNodes, ListEditKind editKind)
: base(originalNode.Span, editKind, visitTrivia: false, originalNode.IsPartOfStructuredTrivia())
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
_originalNode = originalNode;
_newNodes = replacementNodes;
}
[return: NotNullIfNotNull("node")]
public override SyntaxNode? Visit(SyntaxNode? node)
{
if (node == _originalNode)
{
throw GetItemNotListElementException();
}
return base.Visit(node);
}
public override SeparatedSyntaxList<TNode> VisitList<TNode>(SeparatedSyntaxList<TNode> list)
{
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
if (_originalNode is TNode)
{
int num = list.IndexOf((TNode)(object)_originalNode);
if (num >= 0 && num < list.Count)
{
switch (editKind)
{
case ListEditKind.Replace:
return list.ReplaceRange((TNode)(object)_originalNode, _newNodes.Cast<TNode>());
case ListEditKind.InsertAfter:
return list.InsertRange(num + 1, _newNodes.Cast<TNode>());
case ListEditKind.InsertBefore:
return list.InsertRange(num, _newNodes.Cast<TNode>());
}
}
}
return base.VisitList<TNode>(list);
}
public override SyntaxList<TNode> VisitList<TNode>(SyntaxList<TNode> list)
{
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
if (_originalNode is TNode)
{
int num = list.IndexOf((TNode)(object)_originalNode);
if (num >= 0 && num < list.Count)
{
switch (editKind)
{
case ListEditKind.Replace:
return list.ReplaceRange((TNode)(object)_originalNode, _newNodes.Cast<TNode>());
case ListEditKind.InsertAfter:
return list.InsertRange(num + 1, _newNodes.Cast<TNode>());
case ListEditKind.InsertBefore:
return list.InsertRange(num, _newNodes.Cast<TNode>());
}
}
}
return base.VisitList<TNode>(list);
}
}
private class TokenListEditor : BaseListEditor
{
private readonly SyntaxToken _originalToken;
private readonly IEnumerable<SyntaxToken> _newTokens;
public TokenListEditor(SyntaxToken originalToken, IEnumerable<SyntaxToken> newTokens, ListEditKind editKind)
: base(((SyntaxToken)(ref originalToken)).Span, editKind, visitTrivia: false, ((SyntaxToken)(ref originalToken)).IsPartOfStructuredTrivia())
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
_originalToken = originalToken;
_newTokens = newTokens;
}
public override SyntaxToken VisitToken(SyntaxToken token)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (token == _originalToken)
{
throw GetItemNotListElementException();
}
return base.VisitToken(token);
}
public override SyntaxTokenList VisitList(SyntaxTokenList list)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
int num = ((SyntaxTokenList)(ref list)).IndexOf(_originalToken);
if (num >= 0 && num < ((SyntaxTokenList)(ref list)).Count)
{
switch (editKind)
{
case ListEditKind.Replace:
return ((SyntaxTokenList)(ref list)).ReplaceRange(_originalToken, _newTokens);
case ListEditKind.InsertAfter:
return ((SyntaxTokenList)(ref list)).InsertRange(num + 1, _newTokens);
case ListEditKind.InsertBefore:
return ((SyntaxTokenList)(ref list)).InsertRange(num, _newTokens);
}
}
return base.VisitList(list);
}
}
private class TriviaListEditor : BaseListEditor
{
private readonly SyntaxTrivia _originalTrivia;
private readonly IEnumerable<SyntaxTrivia> _newTrivia;
public TriviaListEditor(SyntaxTrivia originalTrivia, IEnumerable<SyntaxTrivia> newTrivia, ListEditKind editKind)
: base(((SyntaxTrivia)(ref originalTrivia)).Span, editKind, visitTrivia: true, ((SyntaxTrivia)(ref originalTrivia)).IsPartOfStructuredTrivia())
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
_originalTrivia = originalTrivia;
_newTrivia = newTrivia;
}
public override SyntaxTriviaList VisitList(SyntaxTriviaList list)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
int num = ((SyntaxTriviaList)(ref list)).IndexOf(_originalTrivia);
if (num >= 0 && num < ((SyntaxTriviaList)(ref list)).Count)
{
switch (editKind)
{
case ListEditKind.Replace:
return ((SyntaxTriviaList)(ref list)).ReplaceRange(_originalTrivia, _newTrivia);
case ListEditKind.InsertAfter:
return ((SyntaxTriviaList)(ref list)).InsertRange(num + 1, _newTrivia);
case ListEditKind.InsertBefore:
return ((SyntaxTriviaList)(ref list)).InsertRange(num, _newTrivia);
}
}
return base.VisitList(list);
}
}
internal static SyntaxNode Replace<TNode>(SyntaxNode root, IEnumerable<TNode>? nodes = null, Func<TNode, TNode, SyntaxNode>? computeReplacementNode = null, IEnumerable<SyntaxToken>? tokens = null, Func<SyntaxToken, SyntaxToken, SyntaxToken>? computeReplacementToken = null, IEnumerable<SyntaxTrivia>? trivia = null, Func<SyntaxTrivia, SyntaxTrivia, SyntaxTrivia>? computeReplacementTrivia = null) where TNode : SyntaxNode
{
Replacer<TNode> replacer = new Replacer<TNode>(nodes, computeReplacementNode, tokens, computeReplacementToken, trivia, computeReplacementTrivia);
if (replacer.HasWork)
{
return replacer.Visit(root);
}
return root;
}
internal static SyntaxToken Replace(SyntaxToken root, IEnumerable<SyntaxNode>? nodes = null, Func<SyntaxNode, SyntaxNode, SyntaxNode>? computeReplacementNode = null, IEnumerable<SyntaxToken>? tokens = null, Func<SyntaxToken, SyntaxToken, SyntaxToken>? computeReplacementToken = null, IEnumerable<SyntaxTrivia>? trivia = null, Func<SyntaxTrivia, SyntaxTrivia, SyntaxTrivia>? computeReplacementTrivia = null)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
Replacer<SyntaxNode> replacer = new Replacer<SyntaxNode>(nodes, computeReplacementNode, tokens, computeReplacementToken, trivia, computeReplacementTrivia);
if (replacer.HasWork)
{
return replacer.VisitToken(root);
}
return root;
}
internal static SyntaxNode ReplaceNodeInList(SyntaxNode root, SyntaxNode originalNode, IEnumerable<SyntaxNode> newNodes)
{
return new NodeListEditor(originalNode, newNodes, ListEditKind.Replace).Visit(root);
}
internal static SyntaxNode InsertNodeInList(SyntaxNode root, SyntaxNode nodeInList, IEnumerable<SyntaxNode> nodesToInsert, bool insertBefore)
{
return new NodeListEditor(nodeInList, nodesToInsert, (!insertBefore) ? ListEditKind.InsertAfter : ListEditKind.InsertBefore).Visit(root);
}
public static SyntaxNode ReplaceTokenInList(SyntaxNode root, SyntaxToken tokenInList, IEnumerable<SyntaxToken> newTokens)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return new TokenListEditor(tokenInList, newTokens, ListEditKind.Replace).Visit(root);
}
public static SyntaxNode InsertTokenInList(SyntaxNode root, SyntaxToken tokenInList, IEnumerable<SyntaxToken> newTokens, bool insertBefore)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return new TokenListEditor(tokenInList, newTokens, (!insertBefore) ? ListEditKind.InsertAfter : ListEditKind.InsertBefore).Visit(root);
}
public static SyntaxNode ReplaceTriviaInList(SyntaxNode root, SyntaxTrivia triviaInList, IEnumerable<SyntaxTrivia> newTrivia)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return new TriviaListEditor(triviaInList, newTrivia, ListEditKind.Replace).Visit(root);
}
public static SyntaxNode InsertTriviaInList(SyntaxNode root, SyntaxTrivia triviaInList, IEnumerable<SyntaxTrivia> newTrivia, bool insertBefore)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return new TriviaListEditor(triviaInList, newTrivia, (!insertBefore) ? ListEditKind.InsertAfter : ListEditKind.InsertBefore).Visit(root);
}
public static SyntaxToken ReplaceTriviaInList(SyntaxToken root, SyntaxTrivia triviaInList, IEnumerable<SyntaxTrivia> newTrivia)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
return new TriviaListEditor(triviaInList, newTrivia, ListEditKind.Replace).VisitToken(root);
}
public static SyntaxToken InsertTriviaInList(SyntaxToken root, SyntaxTrivia triviaInList, IEnumerable<SyntaxTrivia> newTrivia, bool insertBefore)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
return new TriviaListEditor(triviaInList, newTrivia, (!insertBefore) ? ListEditKind.InsertAfter : ListEditKind.InsertBefore).VisitToken(root);
}
private static InvalidOperationException GetItemNotListElementException()
{
return new InvalidOperationException(CodeAnalysisResources.MissingListItem);
}
}