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