Repository: dotnet/roslyn
File: src/Compilers/CSharp/Portable/Syntax/SyntaxTreeDiagnosticEnumerator.cs (C#)

Code before:
            }
            else
            {
                _stack = new NodeIterationStack();
            }
        }

        /// <summary>
        /// Moves the enumerator to the next diagnostic instance in the diagnostic list.
        /// </summary>
        /// <returns>Returns true if enumerator moved to the next diagnostic, false if the
        /// enumerator was at the end of the diagnostic list.</returns>
        public bool MoveNext()
        {
            while (_stack.Any())
            {
                var diagIndex = _stack.Top.DiagnosticIndex;
                var node = _stack.Top.Node;
                var diags = node.GetDiagnostics();
                if (diagIndex < diags.Length - 1)
                {
                    diagIndex++;
                    var sdi = (SyntaxDiagnosticInfo)diags[diagIndex];

                    //for tokens, we've already seen leading trivia on the stack, so we have to roll back for nodes, we
                    //have yet to see the leading trivia.  See documention of _position above.
                    int leadingWidthAlreadyCounted = node.IsToken ? node.GetLeadingTriviaWidth() : 0;

                    // don't produce locations outside of tree span
                    Debug.Assert(_syntaxTree is object);
                    var length = _syntaxTree.GetRoot().FullSpan.Length;
                    var spanStart = Math.Min(_position - leadingWidthAlreadyCounted + sdi.Offset, length);
                    var spanWidth = Math.Min(spanStart + sdi.Width, length) - spanStart;

                    _current = new CSDiagnostic(sdi, new SourceLocation(_syntaxTree, new TextSpan(spanStart, spanWidth)));

                    _stack.UpdateDiagnosticIndexForStackTop(diagIndex);
                    return true;
                }

                var slotIndex = _stack.Top.SlotIndex;
tryAgain:
                if (slotIndex < node.SlotCount - 1)
                {
                    slotIndex++;
                    var child = node.GetSlot(slotIndex);
                    if (child == null)
                    {
                        goto tryAgain;
                    }


Review comment (suggestion):

```suggestion
                    //have yet to see the leading trivia.  See documentation of _position above.
```

Code after:
                    {
                        // For tokens, we've already seen leading trivia (as we push leading/trailing trivia explicit as
                        // green nodes to process on the stack), so we have to roll back.  For nodes, we have yet to see the
                        // leading trivia, so those don't need an adjustment.
                        int leadingWidthAlreadyCounted = node.IsToken ? node.GetLeadingTriviaWidth() : 0;

                        // don't produce locations outside of tree span
                        var length = syntaxTree.GetRoot().FullSpan.Length;
                        var spanStart = Math.Min(position - leadingWidthAlreadyCounted + sdi.Offset, length);
                        var spanWidth = Math.Min(spanStart + sdi.Width, length) - spanStart;

                        yield return new CSDiagnostic(sdi, new SourceLocation(syntaxTree, new TextSpan(spanStart, spanWidth)));
                    }

                    stack.Top.ProcessedDiagnostics = true;
                }

                processNode(node);
            }

            yield break;

            void processNode(GreenNode node)
            {
                // SlotCount is 0 when we hit tokens or normal trivia. In this case, we just want to move past the
                // normal width of the item.  Importantly, in the case of tokens, we don't want to move the full-width.
                // That would make us double-count the widths of the leading/trailing trivia which we're walking into as
                // normal green nodes.
                //
                // As this has no children and has had its diagnostics processed, pop it and process its parent.
                if (node.SlotCount == 0)
                {
                    position += node.Width;
                }
                else
                {
                    for (var nextSlotIndex = stack.Top.SlotIndex + 1; nextSlotIndex < node.SlotCount; nextSlotIndex++)
                    {
                        var child = node.GetSlot(nextSlotIndex);
                        if (child == null)
                            continue;

                        // If the child doesn't have diagnostics anywhere in it, we can skip it entirely.
                        if (!child.ContainsDiagnostics)
                        {
                            position += child.FullWidth;
                            continue;
                        }

                        stack.Top.SlotIndex = nextSlotIndex;
                        stack.PushNodeOrToken(child);