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 : CSharpSyntaxRewriter where TNode : SyntaxNode { private readonly Func? _computeReplacementNode; private readonly Func? _computeReplacementToken; private readonly Func? _computeReplacementTrivia; private readonly HashSet _nodeSet; private readonly HashSet _tokenSet; private readonly HashSet _triviaSet; private readonly HashSet _spanSet; private readonly TextSpan _totalSpan; private readonly bool _visitIntoStructuredTrivia; private readonly bool _shouldVisitTrivia; private static readonly HashSet s_noNodes = new HashSet(); private static readonly HashSet s_noTokens = new HashSet(); private static readonly HashSet s_noTrivia = new HashSet(); public override bool VisitIntoStructuredTrivia => _visitIntoStructuredTrivia; public bool HasWork => _nodeSet.Count + _tokenSet.Count + _triviaSet.Count > 0; public Replacer(IEnumerable? nodes, Func? computeReplacementNode, IEnumerable? tokens, Func? computeReplacementToken, IEnumerable? trivia, Func? 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((IEnumerable)nodes) : s_noNodes); _tokenSet = ((tokens != null) ? new HashSet(tokens) : s_noTokens); _triviaSet = ((trivia != null) ? new HashSet(trivia) : s_noTrivia); _spanSet = new HashSet(_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(_nodeSet, (Func)((SyntaxNode n) => n.IsPartOfStructuredTrivia())) || HashSetExtensions.Any(_tokenSet, (Func)((SyntaxToken t) => ((SyntaxToken)(ref t)).IsPartOfStructuredTrivia())) || HashSetExtensions.Any(_triviaSet, (Func)((SyntaxTrivia t) => ((SyntaxTrivia)(ref t)).IsPartOfStructuredTrivia())); _shouldVisitTrivia = _triviaSet.Count > 0 || _visitIntoStructuredTrivia; } private static TextSpan ComputeTotalSpan(IEnumerable 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 _newNodes; public NodeListEditor(SyntaxNode originalNode, IEnumerable 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 VisitList(SeparatedSyntaxList 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()); case ListEditKind.InsertAfter: return list.InsertRange(num + 1, _newNodes.Cast()); case ListEditKind.InsertBefore: return list.InsertRange(num, _newNodes.Cast()); } } } return base.VisitList(list); } public override SyntaxList VisitList(SyntaxList 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()); case ListEditKind.InsertAfter: return list.InsertRange(num + 1, _newNodes.Cast()); case ListEditKind.InsertBefore: return list.InsertRange(num, _newNodes.Cast()); } } } return base.VisitList(list); } } private class TokenListEditor : BaseListEditor { private readonly SyntaxToken _originalToken; private readonly IEnumerable _newTokens; public TokenListEditor(SyntaxToken originalToken, IEnumerable 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 _newTrivia; public TriviaListEditor(SyntaxTrivia originalTrivia, IEnumerable 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(SyntaxNode root, IEnumerable? nodes = null, Func? computeReplacementNode = null, IEnumerable? tokens = null, Func? computeReplacementToken = null, IEnumerable? trivia = null, Func? computeReplacementTrivia = null) where TNode : SyntaxNode { Replacer replacer = new Replacer(nodes, computeReplacementNode, tokens, computeReplacementToken, trivia, computeReplacementTrivia); if (replacer.HasWork) { return replacer.Visit(root); } return root; } internal static SyntaxToken Replace(SyntaxToken root, IEnumerable? nodes = null, Func? computeReplacementNode = null, IEnumerable? tokens = null, Func? computeReplacementToken = null, IEnumerable? trivia = null, Func? 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 replacer = new Replacer(nodes, computeReplacementNode, tokens, computeReplacementToken, trivia, computeReplacementTrivia); if (replacer.HasWork) { return replacer.VisitToken(root); } return root; } internal static SyntaxNode ReplaceNodeInList(SyntaxNode root, SyntaxNode originalNode, IEnumerable newNodes) { return new NodeListEditor(originalNode, newNodes, ListEditKind.Replace).Visit(root); } internal static SyntaxNode InsertNodeInList(SyntaxNode root, SyntaxNode nodeInList, IEnumerable nodesToInsert, bool insertBefore) { return new NodeListEditor(nodeInList, nodesToInsert, (!insertBefore) ? ListEditKind.InsertAfter : ListEditKind.InsertBefore).Visit(root); } public static SyntaxNode ReplaceTokenInList(SyntaxNode root, SyntaxToken tokenInList, IEnumerable 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 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 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 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 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 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); } }