Beispiel #1
0
        private static void SplitMapDownToFirstMatchNoTrack(FrugalList <SnapshotSpan> unmappedSpans, Predicate <ITextBuffer> match, IList <SnapshotSpan> mappedSpans, bool mapByContentType)
        {
            ITextSnapshot matchingSnapshot = null;

            while (unmappedSpans.Count > 0)
            {
                SnapshotSpan span = unmappedSpans[unmappedSpans.Count - 1];
                unmappedSpans.RemoveAt(unmappedSpans.Count - 1);

                if (span.Snapshot == matchingSnapshot)
                {
                    mappedSpans.Add(span);
                }
                else if (match(span.Snapshot.TextBuffer))
                {
                    mappedSpans.Add(span);
                    matchingSnapshot = span.Snapshot;
                }
                else
                {
                    IProjectionSnapshot spanSnapshotAsProjection = span.Snapshot as IProjectionSnapshot;
                    if (spanSnapshotAsProjection != null &&
                        (!mapByContentType || span.Snapshot.TextBuffer.ContentType.IsOfType("projection")))
                    {
                        unmappedSpans.AddRange(spanSnapshotAsProjection.MapToSourceSnapshots(span));
                    }
                }
            }
        }
Beispiel #2
0
        private static Span MapDownToSnapshot(
            Span span,
            IProjectionSnapshot start,
            ITextSnapshot target
            )
        {
            var sourceSpans = new Queue <SnapshotSpan>(start.MapToSourceSnapshots(span));

            while (true)
            {
                var sourceSpan = sourceSpans.Dequeue();
                if (sourceSpan.Snapshot == target)
                {
                    return(sourceSpan.Span);
                }
                else if (sourceSpan.Snapshot is IProjectionSnapshot)
                {
                    foreach (
                        var s in (sourceSpan.Snapshot as IProjectionSnapshot).MapToSourceSnapshots(
                            sourceSpan.Span
                            )
                        )
                    {
                        sourceSpans.Enqueue(s);
                    }
                }
            }
        }
Beispiel #3
0
        internal static StringRebuilder StringRebuilderFromSnapshotSpan(SnapshotSpan span)
        {
            TextSnapshot snapshot = span.Snapshot as TextSnapshot;

            if (snapshot != null)
            {
                return(snapshot.Content.Substring(span));
            }

            IProjectionSnapshot projectionSnapshot = span.Snapshot as IProjectionSnapshot;

            if (projectionSnapshot != null)
            {
                StringRebuilder content = SimpleStringRebuilder.Create(string.Empty);

                foreach (var childSpan in projectionSnapshot.MapToSourceSnapshots(span))
                {
                    content = content.Append(StringRebuilderFromSnapshotSpan(childSpan));
                }

                return(content);
            }

            //The we don't know what to do fallback. This should never be called unless someone provides a new snapshot
            //implementation.
            return(SimpleStringRebuilder.Create(span.GetText()));
        }
Beispiel #4
0
        internal static void MapDownToBufferNoTrack(SnapshotSpan sourceSpan, ITextBuffer targetBuffer, IList <SnapshotSpan> mappedSpans, bool mapByContentType = false)
        {
            // Most of the time, the sourceSpan will map to the targetBuffer as a single span, rather than being split.
            // Since this method is called a lot, we'll assume first that we'll get a single span and don't need to
            // allocate a stack to keep track of unmapped spans. If that fails we'll fall back on the more expensive approach.
            // Scroll around for a while and this saves a bunch of allocations.
            SnapshotSpan mappedSpan = sourceSpan;

            while (true)
            {
                if (mappedSpan.Snapshot.TextBuffer == targetBuffer)
                {
                    mappedSpans.Add(mappedSpan);
                    return;
                }
                else
                {
                    IProjectionSnapshot mappedSpanProjectionSnapshot = mappedSpan.Snapshot as IProjectionSnapshot;
                    if (mappedSpanProjectionSnapshot != null &&
                        (!mapByContentType || mappedSpanProjectionSnapshot.ContentType.IsOfType("projection")))
                    {
                        var mappedDownSpans = mappedSpanProjectionSnapshot.MapToSourceSnapshots(mappedSpan);
                        if (mappedDownSpans.Count == 1)
                        {
                            mappedSpan = mappedDownSpans[0];
                            continue;
                        }
                        else if (mappedDownSpans.Count == 0)
                        {
                            return;
                        }
                        else
                        {
                            // the projection mapping resulted in more than one span
                            FrugalList <SnapshotSpan> unmappedSpans = new FrugalList <SnapshotSpan>(mappedDownSpans);
                            SplitMapDownToBufferNoTrack(unmappedSpans, targetBuffer, mappedSpans, mapByContentType);
                            return;
                        }
                    }
                    else
                    {
                        // either it's a projection buffer we can't look through, or it's
                        // an ordinary buffer that didn't match
                        return;
                    }
                }
            }
        }
Beispiel #5
0
 private static void MapDownToGround(IList <SnapshotSpan> spans, Dictionary <ITextSnapshot, List <Span> > groundSourceSpansMap)
 {
     foreach (SnapshotSpan span in spans)
     {
         IProjectionSnapshot projSnap = span.Snapshot as IProjectionSnapshot;
         if (projSnap == null)
         {
             List <Span> groundSpans;
             if (!groundSourceSpansMap.TryGetValue(span.Snapshot, out groundSpans))
             {
                 groundSpans = new List <Span>();
                 groundSourceSpansMap.Add(span.Snapshot, groundSpans);
             }
             groundSpans.Add(span);
         }
         else
         {
             MapDownToGround(projSnap.MapToSourceSnapshots(span), groundSourceSpansMap);
         }
     }
 }
Beispiel #6
0
        private static void SplitMapDownToBufferNoTrack(FrugalList <SnapshotSpan> unmappedSpans, ITextBuffer targetBuffer, IList <SnapshotSpan> mappedSpans, bool mapByContentType)
        {
            while (unmappedSpans.Count > 0)
            {
                SnapshotSpan span = unmappedSpans[unmappedSpans.Count - 1];
                unmappedSpans.RemoveAt(unmappedSpans.Count - 1);

                if (span.Snapshot.TextBuffer == targetBuffer)
                {
                    mappedSpans.Add(span);
                }
                else
                {
                    IProjectionSnapshot spanSnapshotAsProjection = span.Snapshot as IProjectionSnapshot;
                    if (spanSnapshotAsProjection != null &&
                        (!mapByContentType || span.Snapshot.TextBuffer.ContentType.IsOfType("projection")))
                    {
                        unmappedSpans.AddRange(spanSnapshotAsProjection.MapToSourceSnapshots(span));
                    }
                }
            }
        }
        private static void ExtendSourceMap(IProjectionSnapshot sourceSnapshot, Span sourceSpan, bool mapByContentType, Dictionary <ITextSnapshot, IList <Span> > allSpans)
        {
            var childSpans = sourceSnapshot.MapToSourceSnapshots(sourceSpan);

            for (int c = 0; (c < childSpans.Count); ++c)
            {
                var childSpan = childSpans[c];
                if (!allSpans.TryGetValue(childSpan.Snapshot, out IList <Span> spans))
                {
                    spans = new FrugalList <Span>();
                    allSpans.Add(childSpan.Snapshot, spans);
                }

                spans.Add(childSpan);

                if ((childSpan.Snapshot is IProjectionSnapshot childProjectionSnapshot) &&
                    (!mapByContentType || childProjectionSnapshot.TextBuffer.ContentType.IsOfType("projection")))
                {
                    ExtendSourceMap(childProjectionSnapshot, childSpan, mapByContentType, allSpans);
                }
            }
        }
Beispiel #8
0
        private static FrugalList <SnapshotSpan> MapDownOneLevel(FrugalList <SnapshotSpan> inputSpans, Predicate <ITextSnapshot> match, ref ITextSnapshot chosenSnapshot, ref FrugalList <Span> targetSpans)
        {
            FrugalList <SnapshotSpan> downSpans = new FrugalList <SnapshotSpan>();

            foreach (SnapshotSpan inputSpan in inputSpans)
            {
                IProjectionBufferBase projBuffer = (IProjectionBufferBase)inputSpan.Snapshot.TextBuffer;
                IProjectionSnapshot   projSnap   = projBuffer.CurrentSnapshot;
                if (projSnap.SourceSnapshots.Count > 0)
                {
                    IList <SnapshotSpan> mappedSpans = projSnap.MapToSourceSnapshots(inputSpan);
                    for (int s = 0; s < mappedSpans.Count; ++s)
                    {
                        SnapshotSpan mappedSpan   = mappedSpans[s];
                        ITextBuffer  mappedBuffer = mappedSpan.Snapshot.TextBuffer;
                        if (mappedBuffer.CurrentSnapshot == chosenSnapshot)
                        {
                            targetSpans.Add(mappedSpan.Span);
                        }
                        else if (chosenSnapshot == null && match(mappedBuffer.CurrentSnapshot))
                        {
                            chosenSnapshot = mappedBuffer.CurrentSnapshot;
                            targetSpans.Add(mappedSpan.Span);
                        }
                        else
                        {
                            IProjectionBufferBase mappedProjBuffer = mappedBuffer as IProjectionBufferBase;
                            if (mappedProjBuffer != null)
                            {
                                downSpans.Add(mappedSpan);
                            }
                        }
                    }
                }
            }
            return(downSpans);
        }
Beispiel #9
0
 private static Span MapDownToSnapshot(Span span, IProjectionSnapshot start, ITextSnapshot target)
 {
     var sourceSpans = new Queue<SnapshotSpan>(start.MapToSourceSnapshots(span));
     while (true)
     {
         var sourceSpan = sourceSpans.Dequeue();
         if (sourceSpan.Snapshot == target)
         {
             return sourceSpan.Span;
         }
         else if (sourceSpan.Snapshot is IProjectionSnapshot)
         {
             foreach (var s in (sourceSpan.Snapshot as IProjectionSnapshot).MapToSourceSnapshots(sourceSpan.Span))
             {
                 sourceSpans.Enqueue(s);
             }
         }
     }
 }