private static bool AreTokensEquivalent(GreenNode before, GreenNode after) { // NOTE(cyrusn): Do we want to drill into trivia? Can documentation ever affect the // global meaning of symbols? This can happen in java with things like the "@obsolete" // clause in doc comment. However, i don't know if anything like that exists in C#. // NOTE(cyrusn): I don't believe we need to examine pp directives. We actually want to // intentionally ignore them as we're only paying attention to the trees that affect // symbolic information. // NOTE(cyrusn): I don't believe we need to examine skipped text. It isn't relevant from // the perspective of global symbolic information. Debug.Assert(before.RawKind == after.RawKind); if (before.IsMissing != after.IsMissing) { return false; } // These are the tokens that don't have fixed text. switch ((SyntaxKind)before.RawKind) { case SyntaxKind.IdentifierToken: return ((Green.SyntaxToken)before).ValueText == ((Green.SyntaxToken)after).ValueText; case SyntaxKind.NumericLiteralToken: case SyntaxKind.CharacterLiteralToken: case SyntaxKind.StringLiteralToken: case SyntaxKind.InterpolatedStringTextToken: return ((Green.SyntaxToken)before).Text == ((Green.SyntaxToken)after).Text; } return true; }
internal ResetPoint(int resetCount, LexerMode mode, int position, GreenNode prevTokenTrailingTrivia) { this.ResetCount = resetCount; this.Mode = mode; this.Position = position; this.PrevTokenTrailingTrivia = prevTokenTrailingTrivia; }
internal WithTwoChildren(GreenNode child0, GreenNode child1) { this.SlotCount = 2; this.AdjustFlagsAndWidth(child0); _child0 = child0; this.AdjustFlagsAndWidth(child1); _child1 = child1; }
internal Enumerator(GreenNode node) { _node = node; _childIndex = -1; _listIndex = -1; _list = null; _currentChild = null; }
internal Enumerator(GreenNode node) { this.node = node; this.childIndex = -1; this.listIndex = -1; this.list = null; this.currentChild = null; }
internal static void NoteGreen(GreenNode node) { Interlocked.Increment(ref stats.greenNodes); if (node.IsToken) { Interlocked.Increment(ref stats.greenTokens); } }
internal SyntaxIdentifierWithTrailingTrivia(string text, GreenNode trailing) : base(text) { if (trailing != null) { this.AdjustFlagsAndWidth(trailing); _trailing = trailing; } }
internal SyntaxIdentifierWithTrailingTrivia(string text, GreenNode trailing, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations) : base(text, diagnostics, annotations) { if (trailing != null) { this.AdjustFlagsAndWidth(trailing); _trailing = trailing; } }
internal WithTwoChildren(ObjectReader reader) : base(reader) { this.SlotCount = 2; _child0 = (GreenNode)reader.ReadValue(); this.AdjustFlagsAndWidth(_child0); _child1 = (GreenNode)reader.ReadValue(); this.AdjustFlagsAndWidth(_child1); }
internal WithTwoChildren(DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations, GreenNode child0, GreenNode child1) : base(diagnostics, annotations) { this.SlotCount = 2; this.AdjustFlagsAndWidth(child0); _child0 = child0; this.AdjustFlagsAndWidth(child1); _child1 = child1; }
internal void Add(GreenNode item) { if (_nodes == null || _count >= _nodes.Length) { this.Grow(_count == 0 ? 8 : _nodes.Length * 2); } _nodes[_count++] = item; }
internal WithThreeChildren(GreenNode child0, GreenNode child1, GreenNode child2) { this.SlotCount = 3; this.AdjustFlagsAndWidth(child0); _child0 = child0; this.AdjustFlagsAndWidth(child1); _child1 = child1; this.AdjustFlagsAndWidth(child2); _child2 = child2; }
internal SyntaxIdentifierWithTrailingTrivia(ObjectReader reader) : base(reader) { var trailing = (GreenNode)reader.ReadValue(); if (trailing != null) { this.AdjustFlagsAndWidth(trailing); _trailing = trailing; } }
internal Enumerator(GreenNode node) { _current = null; _stack = null; _count = 0; if (node != null && node.ContainsDiagnostics) { _stack = new NodeIteration[8]; this.PushNodeOrToken(node); } }
public bool MoveNext() { if (_node != null) { if (_list != null) { if (--_listIndex >= 0) { _currentChild = _list.GetSlot(_listIndex); return true; } _list = null; _listIndex = -1; } while (--_childIndex >= 0) { var child = _node.GetSlot(_childIndex); if (child == null) { continue; } if (child.IsList) { _list = child; _listIndex = _list.SlotCount; if (--_listIndex >= 0) { _currentChild = _list.GetSlot(_listIndex); return true; } else { _list = null; _listIndex = -1; continue; } } else { _currentChild = child; } return true; } } _currentChild = null; return false; }
public bool MoveNext() { if (node != null) { if (this.list != null) { if (--this.listIndex >= 0) { this.currentChild = this.list.GetSlot(this.listIndex); return true; } this.list = null; this.listIndex = -1; } while (--this.childIndex >= 0) { var child = this.node.GetSlot(this.childIndex); if (child == null) { continue; } if (child.IsList) { this.list = child; this.listIndex = this.list.SlotCount; if (--this.listIndex >= 0) { this.currentChild = this.list.GetSlot(this.listIndex); return true; } else { this.list = null; this.listIndex = -1; continue; } } else { this.currentChild = child; } return true; } } this.currentChild = null; return false; }
internal SyntaxTokenWithTrivia(SyntaxKind kind, GreenNode leading, GreenNode trailing, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations) : base(kind, diagnostics, annotations) { if (leading != null) { this.AdjustFlagsAndWidth(leading); this.LeadingField = leading; } if (trailing != null) { this.AdjustFlagsAndWidth(trailing); this.TrailingField = trailing; } }
internal SyntaxTokenWithTrivia(SyntaxKind kind, GreenNode leading, GreenNode trailing) : base(kind) { if (leading != null) { this.AdjustFlagsAndWidth(leading); this.LeadingField = leading; } if (trailing != null) { this.AdjustFlagsAndWidth(trailing); this.TrailingField = trailing; } }
internal SyntaxTreeDiagnosticEnumerator(SyntaxTree syntaxTree, GreenNode node, int position) { this.syntaxTree = null; this.current = null; this.position = position; if (node != null && node.ContainsDiagnostics) { this.syntaxTree = syntaxTree; this.stack = new NodeIterationStack(DefaultStackCapacity); this.stack.PushNodeOrToken(node); } else { this.stack = new NodeIterationStack(); } }
internal SyntaxTokenWithTrivia(ObjectReader reader) : base(reader) { var leading = (GreenNode)reader.ReadValue(); if (leading != null) { this.AdjustFlagsAndWidth(leading); this.LeadingField = leading; } var trailing = (GreenNode)reader.ReadValue(); if (trailing != null) { this.AdjustFlagsAndWidth(trailing); this.TrailingField = trailing; } }
internal Enumerator(GreenNode node) { if (node != null) { _node = node; _childIndex = node.SlotCount; _listIndex = -1; } else { _node = null; _childIndex = 0; _listIndex = -1; } _list = null; _currentChild = null; }
internal Enumerator(GreenNode node) { if (node != null) { this.node = node; this.childIndex = node.SlotCount; this.listIndex = -1; } else { this.node = null; this.childIndex = 0; this.listIndex = -1; } this.list = null; this.currentChild = null; }
internal SyntaxIdentifierWithTrivia( SyntaxKind contextualKind, string text, string valueText, GreenNode leading, GreenNode trailing) : base(contextualKind, text, valueText) { if (leading != null) { this.AdjustFlagsAndWidth(leading); _leading = leading; } if (trailing != null) { this.AdjustFlagsAndWidth(trailing); _trailing = trailing; } }
internal SyntaxIdentifierWithTrivia( SyntaxKind contextualKind, string text, string valueText, GreenNode leading, GreenNode trailing, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations) : base(contextualKind, text, valueText, diagnostics, annotations) { if (leading != null) { this.AdjustFlagsAndWidth(leading); _leading = leading; } if (trailing != null) { this.AdjustFlagsAndWidth(trailing); _trailing = trailing; } }
public override SyntaxToken TokenWithTrailingTrivia(GreenNode trivia) { return(new WhitespaceTokenSyntax(Kind, Text, LeadingTrivia, trivia)); }
internal SyntaxTokenWithValueAndTrivia(SyntaxKind kind, string text, T value, GreenNode leading, GreenNode trailing) : base(kind, text, value) { if (leading != null) { this.AdjustFlagsAndWidth(leading); _leading = leading; } if (trailing != null) { this.AdjustFlagsAndWidth(trailing); _trailing = trailing; } }
internal Green(SyntaxToken.Green lessThanToken, XmlNameSyntax.Green name, GreenNode attributes, SyntaxToken.Green slashGreaterThanToken) : base(SyntaxKind.XmlElementStartTag) { this.SlotCount = 4; this.lessThanToken = lessThanToken; AdjustWidth(lessThanToken); this.name = name; AdjustWidth(name); this.attributes = attributes; AdjustWidth(attributes); this.slashGreaterThanToken = slashGreaterThanToken; AdjustWidth(slashGreaterThanToken); }
internal Reversed(GreenNode node) { _node = node; }
internal static GreenNode List(GreenNode child) { return(child); }
private static bool AreEquivalentRecursive(GreenNode before, GreenNode after, Func <SyntaxKind, bool> ignoreChildNode, bool topLevel) { if (before == after) { return(true); } if (before == null || after == null) { return(false); } if (before.RawKind != after.RawKind) { return(false); } if (before.IsToken) { Debug.Assert(after.IsToken); return(AreTokensEquivalent(before, after)); } if (topLevel) { // Once we get down to the body level we don't need to go any further and we can // consider these trees equivalent. switch ((SyntaxKind)before.RawKind) { case SyntaxKind.Block: case SyntaxKind.ArrowExpressionClause: return(true); } // If we're only checking top level equivalence, then we don't have to go down into // the initializer for a field. However, we can't put that optimization for all // fields. For example, fields that are 'const' do need their initializers checked as // changing them can affect binding results. if ((SyntaxKind)before.RawKind == SyntaxKind.FieldDeclaration) { var fieldBefore = (Green.FieldDeclarationSyntax)before; var fieldAfter = (Green.FieldDeclarationSyntax)after; var isConstBefore = fieldBefore.Modifiers.Any((int)SyntaxKind.ConstKeyword); var isConstAfter = fieldAfter.Modifiers.Any((int)SyntaxKind.ConstKeyword); if (!isConstBefore && !isConstAfter) { ignoreChildNode = childKind => childKind == SyntaxKind.EqualsValueClause; } } // NOTE(cyrusn): Do we want to avoid going down into attribute expressions? I don't // think we can avoid it as there are likely places in the compiler that use these // expressions. For example, if the user changes [InternalsVisibleTo("foo")] to // [InternalsVisibleTo("bar")] then that must count as a top level change as it // affects symbol visibility. Perhaps we could enumerate the places in the compiler // that use the values inside source attributes and we can check if we're in an // attribute with that name. It wouldn't be 100% correct (because of annoying things // like using aliases), but would likely be good enough for the incremental cases in // the IDE. } if (ignoreChildNode != null) { var e1 = before.ChildNodesAndTokens().GetEnumerator(); var e2 = after.ChildNodesAndTokens().GetEnumerator(); while (true) { GreenNode child1 = null; GreenNode child2 = null; // skip ignored children: while (e1.MoveNext()) { var c = e1.Current; if (c != null && (c.IsToken || !ignoreChildNode((SyntaxKind)c.RawKind))) { child1 = c; break; } } while (e2.MoveNext()) { var c = e2.Current; if (c != null && (c.IsToken || !ignoreChildNode((SyntaxKind)c.RawKind))) { child2 = c; break; } } if (child1 == null || child2 == null) { // false if some children remained return(child1 == child2); } if (!AreEquivalentRecursive(child1, child2, ignoreChildNode, topLevel)) { return(false); } } } else { // simple comparison - not ignoring children int slotCount = before.SlotCount; if (slotCount != after.SlotCount) { return(false); } for (int i = 0; i < slotCount; i++) { var child1 = before.GetSlot(i); var child2 = after.GetSlot(i); if (!AreEquivalentRecursive(child1, child2, ignoreChildNode, topLevel)) { return(false); } } return(true); } }
internal WithThreeChildren(DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations, GreenNode child0, GreenNode child1, GreenNode child2) : base(diagnostics, annotations) { this.SlotCount = 3; this.AdjustFlagsAndWidth(child0); _child0 = child0; this.AdjustFlagsAndWidth(child1); _child1 = child1; this.AdjustFlagsAndWidth(child2); _child2 = child2; }
internal static GreenNode TryGetNode(int kind, GreenNode child1, SyntaxFactoryContext context, out int hash) { return(SyntaxNodeCache.TryGetNode(kind, child1, GetNodeFlags(context), out hash)); }
internal ChildSyntaxList(GreenNode node) { _node = node; _count = -1; }
protected WhitespaceTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations) : base(kind, name, leadingTrivia, trailingTrivia, diagnostics, annotations) { }
private static bool AreEquivalentRecursive(GreenNode before, GreenNode after, Func<SyntaxKind, bool> ignoreChildNode, bool topLevel) { if (before == after) { return true; } if (before == null || after == null) { return false; } if (before.RawKind != after.RawKind) { return false; } if (before.IsToken) { Debug.Assert(after.IsToken); return AreTokensEquivalent(before, after); } if (topLevel) { // Once we get down to the body level we don't need to go any further and we can // consider these trees equivalent. switch ((SyntaxKind)before.RawKind) { case SyntaxKind.Block: case SyntaxKind.ArrowExpressionClause: return true; } // If we're only checking top level equivalence, then we don't have to go down into // the initializer for a field. However, we can't put that optimization for all // fields. For example, fields that are 'const' do need their initializers checked as // changing them can affect binding results. if ((SyntaxKind)before.RawKind == SyntaxKind.FieldDeclaration) { var fieldBefore = (Green.FieldDeclarationSyntax)before; var fieldAfter = (Green.FieldDeclarationSyntax)after; var isConstBefore = fieldBefore.Modifiers.Any((int)SyntaxKind.ConstKeyword); var isConstAfter = fieldAfter.Modifiers.Any((int)SyntaxKind.ConstKeyword); if (!isConstBefore && !isConstAfter) { ignoreChildNode = childKind => childKind == SyntaxKind.EqualsValueClause; } } // NOTE(cyrusn): Do we want to avoid going down into attribute expressions? I don't // think we can avoid it as there are likely places in the compiler that use these // expressions. For example, if the user changes [InternalsVisibleTo("foo")] to // [InternalsVisibleTo("bar")] then that must count as a top level change as it // affects symbol visibility. Perhaps we could enumerate the places in the compiler // that use the values inside source attributes and we can check if we're in an // attribute with that name. It wouldn't be 100% correct (because of annoying things // like using aliases), but would likely be good enough for the incremental cases in // the IDE. } if (ignoreChildNode != null) { var e1 = before.ChildNodesAndTokens().GetEnumerator(); var e2 = after.ChildNodesAndTokens().GetEnumerator(); while (true) { GreenNode child1 = null; GreenNode child2 = null; // skip ignored children: while (e1.MoveNext()) { var c = e1.Current; if (c != null && (c.IsToken || !ignoreChildNode((SyntaxKind)c.RawKind))) { child1 = c; break; } } while (e2.MoveNext()) { var c = e2.Current; if (c != null && (c.IsToken || !ignoreChildNode((SyntaxKind)c.RawKind))) { child2 = c; break; } } if (child1 == null || child2 == null) { // false if some children remained return child1 == child2; } if (!AreEquivalentRecursive(child1, child2, ignoreChildNode, topLevel)) { return false; } } } else { // simple comparison - not ignoring children int slotCount = before.SlotCount; if (slotCount != after.SlotCount) { return false; } for (int i = 0; i < slotCount; i++) { var child1 = before.GetSlot(i); var child2 = after.GetSlot(i); if (!AreEquivalentRecursive(child1, child2, ignoreChildNode, topLevel)) { return false; } } return true; } }
internal NodeIteration(GreenNode node) { this.Node = node; this.SlotIndex = -1; this.DiagnosticIndex = -1; }
private void Push(GreenNode node) { if (this.count >= this.stack.Length) { var tmp = new NodeIteration[this.stack.Length * 2]; Array.Copy(this.stack, tmp, this.stack.Length); this.stack = tmp; } this.stack[this.count] = new NodeIteration(node); this.count++; }
protected WhitespaceTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia) : base(kind, name, leadingTrivia, trailingTrivia) { }
public override SyntaxToken TokenWithLeadingTrivia(GreenNode trivia) { return new SyntaxIdentifierWithTrivia(this.contextualKind, this.TextField, this.valueText, trivia, _trailing, this.GetDiagnostics(), this.GetAnnotations()); }
public override SyntaxToken TokenWithTrailingTrivia(GreenNode trivia) { return(new SyntaxTokenWithValueAndTrivia <T>(this.Kind, this.TextField, this.ValueField, _leading, trivia, this.GetDiagnostics(), this.GetAnnotations())); }
internal void PushNodeOrToken(GreenNode node) { var token = node as Syntax.InternalSyntax.SyntaxToken; if (token != null) { PushToken(token); } else { Push(node); } }
private static bool AreEquivalentRecursive(GreenNode before, GreenNode after, Func <int, bool> ignoreChildNode, bool topLevel) { if (before == after) { return(true); } if (before == null || after == null) { return(false); } if (before.RawKind != after.RawKind) { return(false); } if (before.IsToken) { Debug.Assert(after.IsToken); return(AreTokensEquivalent(before, after)); } if (ignoreChildNode != null) { var e1 = before.ChildNodesAndTokens().GetEnumerator(); var e2 = after.ChildNodesAndTokens().GetEnumerator(); while (true) { GreenNode child1 = null; GreenNode child2 = null; // skip ignored children: while (e1.MoveNext()) { var c = e1.Current; if (c != null && (c.IsToken || !ignoreChildNode(c.RawKind))) { child1 = c; break; } } while (e2.MoveNext()) { var c = e2.Current; if (c != null && (c.IsToken || !ignoreChildNode(c.RawKind))) { child2 = c; break; } } if (child1 == null || child2 == null) { // false if some children remained return(child1 == child2); } if (!AreEquivalentRecursive(child1, child2, ignoreChildNode, topLevel)) { return(false); } } } else { // simple comparison - not ignoring children int slotCount = before.SlotCount; if (slotCount != after.SlotCount) { return(false); } for (int i = 0; i < slotCount; i++) { var child1 = before.GetSlot(i); var child2 = after.GetSlot(i); if (!AreEquivalentRecursive(child1, child2, ignoreChildNode, topLevel)) { return(false); } } return(true); } }
internal SyntaxList(GreenNode node) { _node = node; }
internal WhitespaceTokenSyntax(string text, GreenNode leadingTrivia, GreenNode trailingTrivia) : base(SyntaxKind.Whitespace, text, leadingTrivia, trailingTrivia) { }