Files

565 lines
22 KiB
C#
Raw Permalink Normal View History

2026-08-27 10:56:38 -06:00
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax;
internal readonly struct Blender
{
private readonly struct Cursor
{
public readonly SyntaxNodeOrToken CurrentNodeOrToken;
private readonly int _indexInParent;
public bool IsFinished
{
get
{
//IL_0001: 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)
if (CurrentNodeOrToken.Kind() != SyntaxKind.None)
{
return CurrentNodeOrToken.Kind() == SyntaxKind.EndOfFileToken;
}
return true;
}
}
private Cursor(SyntaxNodeOrToken node, int indexInParent)
{
//IL_0001: 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)
CurrentNodeOrToken = node;
_indexInParent = indexInParent;
}
public static Cursor FromRoot(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode node)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return new Cursor(SyntaxNodeOrToken.op_Implicit((SyntaxNode)(object)node), 0);
}
private static bool IsNonZeroWidthOrIsEndOfFile(SyntaxNodeOrToken token)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if (token.Kind() != SyntaxKind.EndOfFileToken)
{
return ((SyntaxNodeOrToken)(ref token)).FullWidth != 0;
}
return true;
}
public Cursor MoveToNextSibling()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: 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_0042: Unknown result type (might be due to invalid IL or missing references)
if (((SyntaxNodeOrToken)(ref CurrentNodeOrToken)).Parent != null)
{
ChildSyntaxList val = ((SyntaxNodeOrToken)(ref CurrentNodeOrToken)).Parent.ChildNodesAndTokens();
int i = _indexInParent + 1;
for (int count = ((ChildSyntaxList)(ref val)).Count; i < count; i++)
{
SyntaxNodeOrToken val2 = ((ChildSyntaxList)(ref val))[i];
if (IsNonZeroWidthOrIsEndOfFile(val2))
{
return new Cursor(val2, i);
}
}
return MoveToParent().MoveToNextSibling();
}
return default(Cursor);
}
private Cursor MoveToParent()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
SyntaxNode parent = ((SyntaxNodeOrToken)(ref CurrentNodeOrToken)).Parent;
return new Cursor(indexInParent: IndexOfNodeInParent(parent), node: SyntaxNodeOrToken.op_Implicit(parent));
}
private static int IndexOfNodeInParent(SyntaxNode node)
{
//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_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
if (node.Parent == null)
{
return 0;
}
ChildSyntaxList val = node.Parent.ChildNodesAndTokens();
int i = SyntaxNodeOrToken.GetFirstChildIndexSpanningPosition(val, ((SyntaxNode)(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode)(object)node).Position);
for (int count = ((ChildSyntaxList)(ref val)).Count; i < count; i++)
{
if (((ChildSyntaxList)(ref val))[i] == SyntaxNodeOrToken.op_Implicit(node))
{
return i;
}
}
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Parser/Blender.Cursor.cs", 107);
}
public Cursor MoveToFirstChild()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: 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)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
SyntaxNode val = ((SyntaxNodeOrToken)(ref CurrentNodeOrToken)).AsNode();
if (val.Kind() == SyntaxKind.InterpolatedStringExpression)
{
SyntaxToken syntaxToken = Lexer.RescanInterpolatedString((InterpolatedStringExpressionSyntax)(object)val.Green);
return new Cursor(SyntaxNodeOrToken.op_Implicit(new SyntaxToken(val.Parent, (GreenNode)(object)syntaxToken, val.Position, _indexInParent)), _indexInParent);
}
if (val.SlotCount > 0)
{
SyntaxNodeOrToken val2 = ChildSyntaxList.ItemInternal(val, 0);
if (IsNonZeroWidthOrIsEndOfFile(val2))
{
return new Cursor(val2, 0);
}
}
int num = 0;
ChildSyntaxList val3 = ((SyntaxNodeOrToken)(ref CurrentNodeOrToken)).ChildNodesAndTokens();
Enumerator enumerator = ((ChildSyntaxList)(ref val3)).GetEnumerator();
while (((Enumerator)(ref enumerator)).MoveNext())
{
SyntaxNodeOrToken current = ((Enumerator)(ref enumerator)).Current;
if (IsNonZeroWidthOrIsEndOfFile(current))
{
return new Cursor(current, num);
}
num++;
}
return default(Cursor);
}
public Cursor MoveToFirstToken()
{
//IL_0011: 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_0028: 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_0022: 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)
Cursor result = this;
if (!result.IsFinished)
{
SyntaxNodeOrToken currentNodeOrToken = result.CurrentNodeOrToken;
while (currentNodeOrToken.Kind() != SyntaxKind.None && !SyntaxFacts.IsAnyToken(currentNodeOrToken.Kind()))
{
result = result.MoveToFirstChild();
currentNodeOrToken = result.CurrentNodeOrToken;
}
}
return result;
}
}
internal struct Reader(Blender blender)
{
private readonly Lexer _lexer = blender._lexer;
private Cursor _oldTreeCursor = blender._oldTreeCursor;
private ImmutableStack<TextChangeRange> _changes = blender._changes;
private int _newPosition = blender._newPosition;
private int _changeDelta = blender._changeDelta;
private DirectiveStack _newDirectives = blender._newDirectives;
private DirectiveStack _oldDirectives = blender._oldDirectives;
private LexerMode _newLexerDrivenMode = blender._newLexerDrivenMode;
internal BlendedNode ReadNodeOrToken(LexerMode mode, bool asToken)
{
BlendedNode blendedNode;
while (true)
{
if (_oldTreeCursor.IsFinished)
{
return ReadNewToken(mode);
}
if (_changeDelta < 0)
{
SkipOldToken();
continue;
}
if (_changeDelta > 0)
{
return ReadNewToken(mode);
}
if (TryTakeOldNodeOrToken(asToken, out blendedNode))
{
break;
}
if (((SyntaxNodeOrToken)(ref _oldTreeCursor.CurrentNodeOrToken)).IsNode)
{
_oldTreeCursor = _oldTreeCursor.MoveToFirstChild();
}
else
{
SkipOldToken();
}
}
return blendedNode;
}
private void SkipOldToken()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
_oldTreeCursor = _oldTreeCursor.MoveToFirstToken();
SyntaxNodeOrToken currentNodeOrToken = _oldTreeCursor.CurrentNodeOrToken;
_changeDelta += ((SyntaxNodeOrToken)(ref currentNodeOrToken)).FullWidth;
_oldDirectives = currentNodeOrToken.ApplyDirectives(_oldDirectives);
_oldTreeCursor = _oldTreeCursor.MoveToNextSibling();
SkipPastChanges();
}
private void SkipPastChanges()
{
//IL_0068: 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_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: 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)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: 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 position = ((SyntaxNodeOrToken)(ref _oldTreeCursor.CurrentNodeOrToken)).Position;
while (!_changes.IsEmpty)
{
TextChangeRange val = _changes.Peek();
TextSpan span = ((TextChangeRange)(ref val)).Span;
if (position >= ((TextSpan)(ref span)).End)
{
TextChangeRange val2 = _changes.Peek();
_changes = _changes.Pop();
int changeDelta = _changeDelta;
int newLength = ((TextChangeRange)(ref val2)).NewLength;
span = ((TextChangeRange)(ref val2)).Span;
_changeDelta = changeDelta + (newLength - ((TextSpan)(ref span)).Length);
continue;
}
break;
}
}
private BlendedNode ReadNewToken(LexerMode mode)
{
SyntaxToken syntaxToken = LexNewToken(mode);
int fullWidth = ((GreenNode)syntaxToken).FullWidth;
_newPosition += fullWidth;
_changeDelta -= fullWidth;
SkipPastChanges();
return CreateBlendedNode(null, syntaxToken);
}
private SyntaxToken LexNewToken(LexerMode mode)
{
if (_lexer.TextWindow.Position != _newPosition)
{
_lexer.Reset(_newPosition, _newDirectives);
}
if (mode >= LexerMode.XmlDocComment)
{
mode |= _newLexerDrivenMode;
}
SyntaxToken result = _lexer.Lex(ref mode);
_newDirectives = _lexer.Directives;
_newLexerDrivenMode = mode & (LexerMode.MaskXmlDocCommentLocation | LexerMode.MaskXmlDocCommentStyle);
return result;
}
private bool TryTakeOldNodeOrToken(bool asToken, out BlendedNode blendedNode)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: 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_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
if (asToken)
{
_oldTreeCursor = _oldTreeCursor.MoveToFirstToken();
}
SyntaxNodeOrToken currentNodeOrToken = _oldTreeCursor.CurrentNodeOrToken;
if (!CanReuse(currentNodeOrToken))
{
blendedNode = default(BlendedNode);
return false;
}
_newPosition += ((SyntaxNodeOrToken)(ref currentNodeOrToken)).FullWidth;
_oldTreeCursor = _oldTreeCursor.MoveToNextSibling();
_newDirectives = currentNodeOrToken.ApplyDirectives(_newDirectives);
_oldDirectives = currentNodeOrToken.ApplyDirectives(_oldDirectives);
Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode node = (Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode)(object)((SyntaxNodeOrToken)(ref currentNodeOrToken)).AsNode();
SyntaxToken val = ((SyntaxNodeOrToken)(ref currentNodeOrToken)).AsToken();
blendedNode = CreateBlendedNode(node, (SyntaxToken)(object)((SyntaxToken)(ref val)).Node);
return true;
}
private bool CanReuse(SyntaxNodeOrToken nodeOrToken)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: 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_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (((SyntaxNodeOrToken)(ref nodeOrToken)).FullWidth == 0)
{
return false;
}
if (((SyntaxNodeOrToken)(ref nodeOrToken)).ContainsAnnotations)
{
return false;
}
if (IntersectsNextChange(nodeOrToken))
{
return false;
}
if (((SyntaxNodeOrToken)(ref nodeOrToken)).ContainsDiagnostics)
{
goto IL_005c;
}
SyntaxToken val;
if (((SyntaxNodeOrToken)(ref nodeOrToken)).IsToken)
{
val = ((SyntaxNodeOrToken)(ref nodeOrToken)).AsToken();
if (((GreenNode)(CSharpSyntaxNode)(object)((SyntaxToken)(ref val)).Node).ContainsSkippedText && ((SyntaxNodeOrToken)(ref nodeOrToken)).Parent.ContainsDiagnostics)
{
goto IL_005c;
}
}
if (IsFabricatedToken(nodeOrToken.Kind()))
{
return false;
}
if (((SyntaxNodeOrToken)(ref nodeOrToken)).IsToken)
{
val = ((SyntaxNodeOrToken)(ref nodeOrToken)).AsToken();
if (((SyntaxToken)(ref val)).IsMissing)
{
goto IL_00a3;
}
}
if (!((SyntaxNodeOrToken)(ref nodeOrToken)).IsNode || !IsIncomplete((Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode)(object)((SyntaxNodeOrToken)(ref nodeOrToken)).AsNode()))
{
if (!((SyntaxNodeOrToken)(ref nodeOrToken)).ContainsDirectives)
{
return true;
}
return _newDirectives.IncrementallyEquivalent(_oldDirectives);
}
goto IL_00a3;
IL_00a3:
return false;
IL_005c:
return false;
}
private bool IntersectsNextChange(SyntaxNodeOrToken nodeOrToken)
{
//IL_0011: 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_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: 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_002d: Unknown result type (might be due to invalid IL or missing references)
if (_changes.IsEmpty)
{
return false;
}
TextSpan fullSpan = ((SyntaxNodeOrToken)(ref nodeOrToken)).FullSpan;
TextChangeRange val = _changes.Peek();
TextSpan span = ((TextChangeRange)(ref val)).Span;
return ((TextSpan)(ref fullSpan)).IntersectsWith(span);
}
private static bool IsIncomplete(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode node)
{
return ((SyntaxNode)node).Green.GetLastTerminal().IsMissing;
}
internal static bool IsFabricatedToken(SyntaxKind kind)
{
if (kind - 8274 <= SyntaxKind.List || kind - 8286 <= SyntaxKind.List)
{
return true;
}
return SyntaxFacts.IsContextualKeyword(kind);
}
private BlendedNode CreateBlendedNode(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode node, SyntaxToken token)
{
return new BlendedNode(node, token, new Blender(_lexer, _oldTreeCursor, _changes, _newPosition, _changeDelta, _newDirectives, _oldDirectives, _newLexerDrivenMode));
}
}
private readonly Lexer _lexer;
private readonly Cursor _oldTreeCursor;
private readonly ImmutableStack<TextChangeRange> _changes;
private readonly int _newPosition;
private readonly int _changeDelta;
private readonly DirectiveStack _newDirectives;
private readonly DirectiveStack _oldDirectives;
private readonly LexerMode _newLexerDrivenMode;
public Blender(Lexer lexer, Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode oldTree, IEnumerable<TextChangeRange> changes)
{
//IL_0016: 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_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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_002b: Unknown result type (might be due to invalid IL or missing references)
_lexer = lexer;
_changes = ImmutableStack.Create<TextChangeRange>();
if (changes != null)
{
TextChangeRange changeRange = TextChangeRange.Collapse(changes);
TextChangeRange value = ExtendToAffectedRange(oldTree, changeRange);
_changes = _changes.Push(value);
}
if (oldTree == null)
{
_oldTreeCursor = default(Cursor);
_newPosition = lexer.TextWindow.Position;
}
else
{
_oldTreeCursor = Cursor.FromRoot(oldTree).MoveToFirstChild();
_newPosition = 0;
}
_changeDelta = 0;
_newDirectives = default(DirectiveStack);
_oldDirectives = default(DirectiveStack);
_newLexerDrivenMode = LexerMode.XmlDocCommentLocationStart;
}
private Blender(Lexer lexer, Cursor oldTreeCursor, ImmutableStack<TextChangeRange> changes, int newPosition, int changeDelta, DirectiveStack newDirectives, DirectiveStack oldDirectives, LexerMode newLexerDrivenMode)
{
_lexer = lexer;
_oldTreeCursor = oldTreeCursor;
_changes = changes;
_newPosition = newPosition;
_changeDelta = changeDelta;
_newDirectives = newDirectives;
_oldDirectives = oldDirectives;
_newLexerDrivenMode = newLexerDrivenMode & (LexerMode.MaskXmlDocCommentLocation | LexerMode.MaskXmlDocCommentStyle);
}
private static TextChangeRange ExtendToAffectedRange(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode oldTree, TextChangeRange changeRange)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
int val = ((SyntaxNode)oldTree).FullWidth - 1;
TextSpan span = ((TextChangeRange)(ref changeRange)).Span;
int num = Math.Max(Math.Min(((TextSpan)(ref span)).Start, val), 0);
int num2 = 0;
while (num > 0 && num2 <= 1)
{
SyntaxToken val2 = oldTree.FindToken(num);
num = Math.Max(0, ((SyntaxToken)(ref val2)).Position - 1);
if (((SyntaxToken)(ref val2)).FullWidth > 0)
{
num2++;
}
}
if (IsInsideInterpolation(oldTree, num))
{
FileLinePositionSpan lineSpan = oldTree.SyntaxTree.GetLineSpan(new TextSpan(num, 0), default(CancellationToken));
LinePositionSpan span2 = ((FileLinePositionSpan)(ref lineSpan)).Span;
LinePosition start = ((LinePositionSpan)(ref span2)).Start;
int character = ((LinePosition)(ref start)).Character;
num = Math.Max(num - character, 0);
}
int num3 = num;
span = ((TextChangeRange)(ref changeRange)).Span;
TextSpan val3 = TextSpan.FromBounds(num3, ((TextSpan)(ref span)).End);
int newLength = ((TextChangeRange)(ref changeRange)).NewLength;
span = ((TextChangeRange)(ref changeRange)).Span;
int num4 = newLength + (((TextSpan)(ref span)).Start - num);
return new TextChangeRange(val3, num4);
}
private static bool IsInsideInterpolation(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode oldTree, int start)
{
//IL_0003: 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)
SyntaxToken val = oldTree.FindToken(start);
for (SyntaxNode parent = ((SyntaxToken)(ref val)).Parent; parent != null; parent = parent.Parent)
{
if (parent.Kind() == SyntaxKind.InterpolatedStringExpression)
{
return true;
}
}
return false;
}
public BlendedNode ReadNode(LexerMode mode)
{
return ReadNodeOrToken(mode, asToken: false);
}
public BlendedNode ReadToken(LexerMode mode)
{
return ReadNodeOrToken(mode, asToken: true);
}
private BlendedNode ReadNodeOrToken(LexerMode mode, bool asToken)
{
return new Reader(this).ReadNodeOrToken(mode, asToken);
}
}