示例#1
0
        private void AddSourceBuffer(IProjectionBufferBase projBuffer, ITextBuffer sourceBuffer, FrugalList <ITextBuffer> addedToGraphBuffers)
        {
            bool firstEncounter = false;
            FrugalList <IProjectionBufferBase> importingProjectionBuffers;

            if (!this.importingProjectionBufferMap.TryGetValue(sourceBuffer, out importingProjectionBuffers))
            {
                // sourceBuffer is new to this buffer graph
                addedToGraphBuffers.Add(sourceBuffer);
                firstEncounter = true;

                importingProjectionBuffers = new FrugalList <IProjectionBufferBase>();
                this.importingProjectionBufferMap.Add(sourceBuffer, importingProjectionBuffers);

                this.eventHooks.Add(new WeakEventHookForBufferGraph(this, sourceBuffer));
            }
            importingProjectionBuffers.Add(projBuffer);

            if (firstEncounter)
            {
                IProjectionBufferBase addedProjBufferBase = sourceBuffer as IProjectionBufferBase;
                if (addedProjBufferBase != null)
                {
                    foreach (ITextBuffer furtherSourceBuffer in addedProjBufferBase.SourceBuffers)
                    {
                        AddSourceBuffer(addedProjBufferBase, furtherSourceBuffer, addedToGraphBuffers);
                    }
                }
            }
        }
示例#2
0
        private void PopulateSourceEdits(ITextBuffer buffer)
        {
            IProjectionBufferBase projectionBuffer = buffer as IProjectionBufferBase;

            if (projectionBuffer != null)
            {
                // Add ITextEdit objects to the edit map for all source buffers of the current projection buffer that
                // are themselves projection buffers. This is so that such buffers are not considered independent buffers
                // if it happens that the master edit does not touch them directly (even though not touched directly, they
                // may receive events from their source buffers that were touched directly, and so FinalApply() will need
                // to be invoked on them in order to construct a snapshot that matches the last snapshots of their source buffers).
                foreach (ITextBuffer sourceBuffer in projectionBuffer.SourceBuffers)
                {
                    IProjectionBufferBase sourceProjectionBuffer = sourceBuffer as IProjectionBufferBase;
                    if (sourceProjectionBuffer != null)
                    {
                        BaseBuffer baseSourceBuffer = (BaseBuffer)sourceBuffer;
                        if (!this.buffer2EditMap.ContainsKey(baseSourceBuffer))
                        {
                            this.buffer2EditMap.Add(sourceBuffer, (baseSourceBuffer.CreateSubordinateEdit(this.masterOptions, null, this.masterEditTag)));
                        }
                    }
                }
            }
        }
示例#3
0
        private void RemoveSourceBuffer(IProjectionBufferBase projBuffer, ITextBuffer sourceBuffer, FrugalList <ITextBuffer> removedFromGraphBuffers)
        {
            IList <IProjectionBufferBase> importingProjectionBuffers = this.importingProjectionBufferMap[sourceBuffer];

            importingProjectionBuffers.Remove(projBuffer);
            if (importingProjectionBuffers.Count == 0)
            {
                removedFromGraphBuffers.Add(sourceBuffer);
                this.importingProjectionBufferMap.Remove(sourceBuffer);

                for (int i = 0; (i < this.eventHooks.Count); ++i)
                {
                    if (this.eventHooks[i].SourceBuffer == sourceBuffer)
                    {
                        this.eventHooks[i].UnsubscribeFromSourceBuffer();
                        this.eventHooks.RemoveAt(i);
                        break;
                    }
                }

                IProjectionBufferBase removedProjBufferBase = sourceBuffer as IProjectionBufferBase;
                if (removedProjBufferBase != null)
                {
                    foreach (ITextBuffer furtherSourceBuffer in removedProjBufferBase.SourceBuffers)
                    {
                        RemoveSourceBuffer(removedProjBufferBase, furtherSourceBuffer, removedFromGraphBuffers);
                    }
                }
            }
        }
示例#4
0
        private void BuildGraph()
        {
            // Police this.members by removing the expired ones
            this.members.RemoveWhere((member) => member.Buffer == null);

            this.graph = new Dictionary <BaseBuffer, GraphEntry>(this.members.Count);
            foreach (BufferWeakReference bufferWeakReference in this.members)
            {
                var buffer = bufferWeakReference.Buffer;
                if (buffer != null)     //There could have been a GC between the police action above and here.
                {
                    graph.Add(buffer, new GraphEntry(new HashSet <IProjectionBufferBase>(), false, false));
                }
            }
            foreach (BufferWeakReference bufferWeakReference in this.members)
            {
                IProjectionBufferBase p = bufferWeakReference.Buffer as IProjectionBufferBase;
                if (p != null)
                {
                    foreach (BaseBuffer source in p.SourceBuffers)
                    {
                        graph[source].Targets.Add(p);
                    }
                }
            }
            MarkMasterClosure(this.masterBuffer);
        }
示例#5
0
 private static bool IsSourceBuffer(IProjectionBufferBase top, ITextBuffer bottom)
 {
     return(top.SourceBuffers.Contains(bottom) ||
            top.SourceBuffers
            .OfType <IProjectionBufferBase>()
            .Any(b => IsSourceBuffer(b, bottom)));
 }
示例#6
0
        private void SourceBuffersChanged(object sender, ProjectionSourceBuffersChangedEventArgs e)
        {
            IProjectionBufferBase    projBuffer              = (IProjectionBufferBase)sender;
            FrugalList <ITextBuffer> addedToGraphBuffers     = new FrugalList <ITextBuffer>();
            FrugalList <ITextBuffer> removedFromGraphBuffers = new FrugalList <ITextBuffer>();

            foreach (ITextBuffer addedBuffer in e.AddedBuffers)
            {
                AddSourceBuffer(projBuffer, addedBuffer, addedToGraphBuffers);
            }

            foreach (ITextBuffer removedBuffer in e.RemovedBuffers)
            {
                RemoveSourceBuffer(projBuffer, removedBuffer, removedFromGraphBuffers);
            }

            if (addedToGraphBuffers.Count > 0 || removedFromGraphBuffers.Count > 0)
            {
                var listeners = GraphBuffersChanged;
                if (listeners != null)
                {
                    ((BaseBuffer)projBuffer).group.EnqueueEvents
                        (new GraphEventRaiser(this, new GraphBuffersChangedEventArgs(addedToGraphBuffers, removedFromGraphBuffers)), null);
                }
            }
        }
示例#7
0
        public BufferGraph(ITextBuffer topBuffer, GuardedOperations guardedOperations)
        {
            if (topBuffer == null)
            {
                throw new ArgumentNullException("topBuffer");
            }
            if (guardedOperations == null)
            {
                throw new ArgumentNullException("guardedOperations");
            }

            this.topBuffer         = topBuffer;
            this.guardedOperations = guardedOperations;

            this.importingProjectionBufferMap.Add(topBuffer, null);
            // The top buffer has no targets, but it is put here so membership in this map can be used uniformly
            // to determine whether a buffer is in the buffer graph

            // Subscribe to content type changed events on the toplevel buffer
            this.eventHooks.Add(new WeakEventHookForBufferGraph(this, topBuffer));

            IProjectionBufferBase projectionBufferBase = topBuffer as IProjectionBufferBase;

            if (projectionBufferBase != null)
            {
                IList <ITextBuffer>      sourceBuffers = projectionBufferBase.SourceBuffers;
                FrugalList <ITextBuffer> dontCare      = new FrugalList <ITextBuffer>();
                foreach (ITextBuffer sourceBuffer in sourceBuffers)
                {
                    AddSourceBuffer(projectionBufferBase, sourceBuffer, dontCare);
                }
            }
        }
示例#8
0
        private void RaiseProjectionBufferCreatedEvent(IProjectionBufferBase buffer)
        {
            EventHandler <TextBufferCreatedEventArgs> handler = ProjectionBufferCreated;

            if (handler != null)
            {
                handler(this, new TextBufferCreatedEventArgs(buffer));
            }
        }
示例#9
0
        public SnapshotPoint?MapDownToFirstMatch(SnapshotPoint position, PointTrackingMode trackingMode, Predicate <ITextSnapshot> match, PositionAffinity affinity)
        {
            if (position.Snapshot == null)
            {
                throw new ArgumentNullException("position");
            }
            if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative)
            {
                throw new ArgumentOutOfRangeException("trackingMode");
            }
            if (match == null)
            {
                throw new ArgumentNullException("match");
            }
            if (affinity < PositionAffinity.Predecessor || affinity > PositionAffinity.Successor)
            {
                throw new ArgumentOutOfRangeException("affinity");
            }
            if (!this.importingProjectionBufferMap.ContainsKey(position.Snapshot.TextBuffer))
            {
                return(null);
            }

            ITextBuffer   currentBuffer   = position.Snapshot.TextBuffer;
            ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot;
            int           currentPosition = position.TranslateTo(currentSnapshot, trackingMode).Position;

            while (!match(currentSnapshot))
            {
                IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase;
                if (projBuffer == null)
                {
                    return(null);
                }
                IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot;
                if (projSnap.SourceSnapshots.Count == 0)
                {
                    return(null);
                }
                SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition, affinity);
                currentPosition = currentPoint.Position;
                currentSnapshot = currentPoint.Snapshot;
                currentBuffer   = currentSnapshot.TextBuffer;
            }
            return(new SnapshotPoint(currentSnapshot, currentPosition));
        }
        private void Traverse(ITextBuffer buffer, List <ITextBuffer> result, HashSet <ITextBuffer> processed)
        {
            processed.Add(buffer);
            IProjectionBufferBase proj = buffer as IProjectionBufferBase;

            if (proj != null)
            {
                foreach (ITextBuffer sourceBuffer in proj.SourceBuffers)
                {
                    if (!processed.Contains(sourceBuffer))
                    {
                        Traverse(sourceBuffer, result, processed);
                    }
                }
            }
            result.Add(buffer);
        }
示例#11
0
        private void MarkMasterClosure(BaseBuffer buffer)
        {
            GraphEntry g = this.graph[buffer];

            if (!g.Dependent)
            {
                g.Dependent = true;
                IProjectionBufferBase projectionBuffer = buffer as IProjectionBufferBase;
                if (projectionBuffer != null)
                {
                    foreach (BaseBuffer source in projectionBuffer.SourceBuffers)
                    {
                        MarkMasterClosure(source);
                    }
                }
            }
        }
示例#12
0
        public SnapshotPoint?MapDownToBuffer(SnapshotPoint position, PointTrackingMode trackingMode, ITextBuffer targetBuffer, PositionAffinity affinity)
        {
            if (position.Snapshot == null)
            {
                throw new ArgumentNullException("position");
            }
            if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative)
            {
                throw new ArgumentOutOfRangeException("trackingMode");
            }
            if (targetBuffer == null)
            {
                throw new ArgumentNullException("targetBuffer");
            }
            if (affinity < PositionAffinity.Predecessor || affinity > PositionAffinity.Successor)
            {
                throw new ArgumentOutOfRangeException("affinity");
            }

            ITextBuffer   currentBuffer   = position.Snapshot.TextBuffer;
            ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot;
            int           currentPosition = position.TranslateTo(currentSnapshot, trackingMode).Position;

            while (currentBuffer != targetBuffer)
            {
                IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase;
                if (projBuffer == null)
                {
                    return(null);
                }
                IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot;
                if (projSnap.SourceSnapshots.Count == 0)
                {
                    return(null);
                }
                SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition, affinity);
                currentPosition = currentPoint.Position;
                currentSnapshot = currentPoint.Snapshot;
                currentBuffer   = currentSnapshot.TextBuffer;
            }

            return(new SnapshotPoint(currentSnapshot, currentPosition));
        }
示例#13
0
        public SnapshotPoint?MapDownToInsertionPoint(SnapshotPoint position, PointTrackingMode trackingMode, Predicate <ITextSnapshot> match)
        {
            if (position.Snapshot == null)
            {
                throw new ArgumentNullException("position");
            }
            if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative)
            {
                throw new ArgumentOutOfRangeException("trackingMode");
            }
            if (match == null)
            {
                throw new ArgumentNullException("match");
            }

            ITextBuffer   currentBuffer   = position.Snapshot.TextBuffer;
            int           currentPosition = position.TranslateTo(currentBuffer.CurrentSnapshot, trackingMode);
            ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot;

            while (!match(currentSnapshot))
            {
                IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase;
                if (projBuffer == null)
                {
                    return(null);
                }
                IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot;
                if (projSnap.SourceSnapshots.Count == 0)
                {
                    return(null);
                }
                SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition);
                currentPosition = currentPoint.Position;
                currentSnapshot = currentPoint.Snapshot;
                currentBuffer   = currentSnapshot.TextBuffer;
            }
            return(new SnapshotPoint(currentSnapshot, currentPosition));
        }
示例#14
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);
        }
示例#15
0
 public IDifferenceBuffer TryGetDifferenceBuffer(IProjectionBufferBase projectionBuffer) => throw new System.NotImplementedException();
示例#16
0
 private static bool IsSourceBuffer(IProjectionBufferBase top, ITextBuffer bottom)
 {
     return top.SourceBuffers.Contains(bottom) ||
         top.SourceBuffers.OfType<IProjectionBufferBase>().Any(b => IsSourceBuffer(b, bottom));
 }
示例#17
0
 private static bool IsSourceBuffer(IProjectionBufferBase top, ITextBuffer bottom)
 {
     return top.SourceBuffers.Contains(bottom) || top.SourceBuffers.Any((ITextBuffer tb) => tb is IProjectionBufferBase && IsSourceBuffer((IProjectionBufferBase)tb, bottom));
 }
示例#18
0
 private static bool IsSourceBuffer(IProjectionBufferBase top, ITextBuffer bottom)
 {
     return(top.SourceBuffers.Contains(bottom) || top.SourceBuffers.Any((ITextBuffer tb) => tb is IProjectionBufferBase && IsSourceBuffer((IProjectionBufferBase)tb, bottom)));
 }