public static NormalizedTextSpanCollection Difference()

in vsintegration/src/FSharp.LanguageService.Base/PatternMatcher/NormalizedTextSpanCollection.cs [252:336]


        public static NormalizedTextSpanCollection Difference(NormalizedTextSpanCollection left, NormalizedTextSpanCollection right)
        {
            if (left == null)
            {
                throw new ArgumentNullException(nameof(left));
            }

            if (right == null)
            {
                throw new ArgumentNullException(nameof(right));
            }

            if (left.Count == 0)
            {
                return left;
            }

            if (right.Count == 0)
            {
                return left;
            }

            OrderedSpanList spans = new OrderedSpanList();

            int index1 = 0;
            int index2 = 0;
            int lastEnd = -1;
            do
            {
                TextSpan span1 = left[index1];
                TextSpan span2 = right[index2];

                if ((span2.Length == 0) || (span1.Start >= span2.End))
                {
                    ++index2;
                }
                else if (span1.End <= span2.Start)
                {
                    // lastEnd is set to the end of the previously encountered intersecting span
                    // from right when it ended before the end of span1 (so it must still be less
                    // than the end of span1).
                    Debug.Assert(lastEnd < span1.End);
                    spans.Add(TextSpan.FromBounds(Math.Max(lastEnd, span1.Start), span1.End));
                    ++index1;
                }
                else
                {
                    // The spans intersect, so add anything from span1 that extends to the left of span2.
                    if (span1.Start < span2.Start)
                    {
                        // lastEnd is set to the end of the previously encountered intersecting span
                        // on span2, so it must be less than the start of the current span on span2.
                        Debug.Assert(lastEnd < span2.Start);
                        spans.Add(TextSpan.FromBounds(Math.Max(lastEnd, span1.Start), span2.Start));
                    }

                    if (span1.End < span2.End)
                    {
                        ++index1;
                    }
                    else if (span1.End == span2.End)
                    {
                        // Both spans ended at the same place so we're done with both.
                        ++index1;
                        ++index2;
                    }
                    else
                    {
                        // span2 ends before span1, so keep track of where it ended so that we don't
                        // try to add the excluded portion the next time we add a span.
                        lastEnd = span2.End;
                        ++index2;
                    }
                }
            }
            while ((index1 < left.Count) && (index2 < right.Count));

            while (index1 < left.Count)
            {
                TextSpan span1 = left[index1++];
                spans.Add(TextSpan.FromBounds(Math.Max(lastEnd, span1.Start), span1.End));
            }

            return new NormalizedTextSpanCollection(spans);
        }