public IElisionBuffer CreateElisionBuffer(IProjectionEditResolver projectionEditResolver, NormalizedSnapshotSpanCollection exposedSpans, ElisionBufferOptions options, IContentType contentType) { // projectionEditResolver is allowed to be null. if (exposedSpans == null) { throw new ArgumentNullException(nameof(exposedSpans)); } if (exposedSpans.Count == 0) { throw new ArgumentOutOfRangeException(nameof(exposedSpans)); // really? } if (contentType == null) { throw new ArgumentNullException(nameof(contentType)); } if (exposedSpans[0].Snapshot != exposedSpans[0].Snapshot.TextBuffer.CurrentSnapshot) { // TODO: // build against given snapshot and then move forward if necessary? throw new ArgumentException("Elision buffer must be created against the current snapshot of its source buffer"); } IElisionBuffer buffer = new ElisionBuffer(projectionEditResolver, contentType, exposedSpans[0].Snapshot.TextBuffer, exposedSpans, options, _textDifferencingSelectorService.DefaultTextDifferencingService, _guardedOperations); RaiseProjectionBufferCreatedEvent(buffer); return(buffer); }
public ElisionBuffer(IProjectionEditResolver resolver, IContentType contentType, ITextBuffer sourceBuffer, NormalizedSpanCollection exposedSpans, ElisionBufferOptions options, ITextDifferencingService textDifferencingService, GuardedOperations guardedOperations) : base(resolver, contentType, textDifferencingService, guardedOperations) { Debug.Assert(sourceBuffer != null); this.sourceBuffer = sourceBuffer; this.sourceSnapshot = sourceBuffer.CurrentSnapshot; BaseBuffer baseSourceBuffer = (BaseBuffer)sourceBuffer; this.eventHook = new WeakEventHook(this, baseSourceBuffer); this.group = baseSourceBuffer.group; this.group.AddMember(this); this.content = new ElisionMap(this.sourceSnapshot, exposedSpans); StringRebuilder newBuilder = StringRebuilder.Empty; for (int i = 0; (i < exposedSpans.Count); ++i) { newBuilder = newBuilder.Append(BufferFactoryService.StringRebuilderFromSnapshotAndSpan(this.sourceSnapshot, exposedSpans[i])); } this.builder = newBuilder; this.elisionOptions = options; this.currentVersion.SetLength(content.Length); this.currentElisionSnapshot = new ElisionSnapshot(this, this.sourceSnapshot, base.currentVersion, this.builder, this.content, (options & ElisionBufferOptions.FillInMappingMode) != 0); this.currentSnapshot = this.currentElisionSnapshot; }
public ElisionBuffer(IProjectionEditResolver resolver, IContentType contentType, ITextBuffer sourceBuffer, NormalizedSpanCollection exposedSpans, ElisionBufferOptions options, ITextDifferencingService textDifferencingService, GuardedOperations guardedOperations) : base(resolver, contentType, textDifferencingService, guardedOperations) { Debug.Assert(sourceBuffer != null); this.sourceBuffer = sourceBuffer; this.sourceSnapshot = sourceBuffer.CurrentSnapshot; BaseBuffer baseSourceBuffer = (BaseBuffer)sourceBuffer; this.eventHook = new WeakEventHook(this, baseSourceBuffer); this.group = baseSourceBuffer.group; this.group.AddMember(this); this.content = new ElisionMap(this.sourceSnapshot, exposedSpans); this.elisionOptions = options; this.currentVersion.InternalLength = content.Length; this.currentElisionSnapshot = new ElisionSnapshot(this, this.sourceSnapshot, base.currentVersion, this.content, (options & ElisionBufferOptions.FillInMappingMode) != 0); this.currentSnapshot = this.currentElisionSnapshot; }
public IProjectionBuffer CreateProjectionBuffer(IProjectionEditResolver projectionEditResolver, IList <object> trackingSpans, ProjectionBufferOptions options) { // projectionEditResolver is allowed to be null. if (trackingSpans == null) { throw new ArgumentNullException(nameof(trackingSpans)); } IProjectionBuffer buffer = new ProjectionBuffer(this, projectionEditResolver, ProjectionContentType, trackingSpans, _differenceService, _textDifferencingSelectorService.DefaultTextDifferencingService, options, _guardedOperations); RaiseProjectionBufferCreatedEvent(buffer); return(buffer); }
public ProjectionBufferManager(ITextBuffer diskBuffer, IProjectionBufferFactoryService projectionBufferFactoryService, IContentTypeRegistryService contentTypeRegistryService, string topLevelContentTypeName, string secondaryContentTypeName) { DiskBuffer = diskBuffer; _contentTypeRegistryService = contentTypeRegistryService; _editResolver = new LanguageEditResolver(diskBuffer); var contentType = _contentTypeRegistryService.GetContentType(topLevelContentTypeName); ViewBuffer = projectionBufferFactoryService.CreateProjectionBuffer(_editResolver, new List <object>(0), ProjectionBufferOptions.None, contentType); contentType = _contentTypeRegistryService.GetContentType(secondaryContentTypeName); ContainedLanguageBuffer = projectionBufferFactoryService.CreateProjectionBuffer(_editResolver, new List <object>(0), ProjectionBufferOptions.WritableLiteralSpans, contentType); ServiceManager.AddService <IProjectionBufferManager>(this, DiskBuffer); ServiceManager.AddService <IProjectionBufferManager>(this, ViewBuffer); }
/// <summary> /// Creates a TestHostDocument backed by a projection buffer. The surface buffer is /// described by a markup string with {|name:|} style pointers to annotated spans that can /// be found in one of a set of provided documents. Unnamed spans in the documents (which /// must have both endpoints inside an annotated spans) and in the surface buffer markup are /// mapped and included in the resulting document. /// /// If the markup string has the caret indicator "$$", then the caret will be placed at the /// corresponding position. If it does not, then the first span mapped into the projection /// buffer that contains the caret from its document is used. /// /// The result is a new TestHostDocument backed by a projection buffer including tracking /// spans from any number of documents and inert text from the markup itself. /// /// As an example, consider surface buffer markup /// ABC [|DEF|] [|GHI[|JKL|]|]{|S1:|} [|MNO{|S2:|}PQR S$$TU|] {|S4:|}{|S5:|}{|S3:|} /// /// This contains 4 unnamed spans and references to 5 spans that should be found and /// included. Consider an included base document created from the following markup: /// /// public class C /// { /// public void M1() /// { /// {|S1:int [|abc[|d$$ef|]|] = foo;|} /// int y = foo; /// {|S2:int [|def|] = foo;|} /// int z = {|S3:123|} + {|S4:456|} + {|S5:789|}; /// } /// } /// /// The resulting projection buffer (with unnamed span markup preserved) would look like: /// ABC [|DEF|] [|GHI[|JKL|]|]int [|abc[|d$$ef|]|] = foo; [|MNOint [|def|] = foo;PQR S$$TU|] 456789123 /// /// The union of unnamed spans from the surface buffer markup and each of the projected /// spans is sorted as it would have been sorted by MarkupTestFile had it parsed the entire /// projection buffer as one file, which it would do in a stack-based manner. In our example, /// the order of the unnamed spans would be as follows: /// /// ABC [|DEF|] [|GHI[|JKL|]|]int [|abc[|d$$ef|]|] = foo; [|MNOint [|def|] = foo;PQR S$$TU|] 456789123 /// -----1 -----2 -------4 -----6 /// ------------3 --------------5 --------------------------------7 /// </summary> /// <param name="markup">Describes the surface buffer, and contains a mix of inert text, /// named spans and unnamed spans. Any named spans must contain only the name portion /// (e.g. {|Span1:|} which must match the name of a span in one of the baseDocuments. /// Annotated spans cannot be nested but they can be adjacent, in which case order will be /// preserved. The markup may also contain the caret indicator.</param> /// <param name="baseDocuments">The set of documents from which the projection buffer /// document will be composed.</param> /// <returns></returns> public TestHostDocument CreateProjectionBufferDocument(string markup, IList <TestHostDocument> baseDocuments, string languageName, string path = "projectionbufferdocumentpath", ProjectionBufferOptions options = ProjectionBufferOptions.None, IProjectionEditResolver editResolver = null) { IList <object> projectionBufferSpans; Dictionary <string, IList <TextSpan> > mappedSpans; int?mappedCaretLocation; GetSpansAndCaretFromSurfaceBufferMarkup(markup, baseDocuments, out projectionBufferSpans, out mappedSpans, out mappedCaretLocation); var projectionBufferFactory = this.GetService <IProjectionBufferFactoryService>(); var projectionBuffer = projectionBufferFactory.CreateProjectionBuffer(editResolver, projectionBufferSpans, options); // Add in mapped spans from each of the base documents foreach (var document in baseDocuments) { mappedSpans[string.Empty] = mappedSpans.ContainsKey(string.Empty) ? mappedSpans[string.Empty] : new List <TextSpan>(); foreach (var span in document.SelectedSpans) { var snapshotSpan = span.ToSnapshotSpan(document.TextBuffer.CurrentSnapshot); var mappedSpan = projectionBuffer.CurrentSnapshot.MapFromSourceSnapshot(snapshotSpan).Single(); mappedSpans[string.Empty].Add(mappedSpan.ToTextSpan()); } // Order unnamed spans as they would be ordered by the normal span finding // algorithm in MarkupTestFile mappedSpans[string.Empty] = mappedSpans[string.Empty].OrderBy(s => s.End).ThenBy(s => - s.Start).ToList(); foreach (var kvp in document.AnnotatedSpans) { mappedSpans[kvp.Key] = mappedSpans.ContainsKey(kvp.Key) ? mappedSpans[kvp.Key] : new List <TextSpan>(); foreach (var span in kvp.Value) { var snapshotSpan = span.ToSnapshotSpan(document.TextBuffer.CurrentSnapshot); var mappedSpan = projectionBuffer.CurrentSnapshot.MapFromSourceSnapshot(snapshotSpan).Single(); mappedSpans[kvp.Key].Add(mappedSpan.ToTextSpan()); } } } var languageServices = this.Services.GetLanguageServices(languageName); var projectionDocument = new TestHostDocument( TestExportProvider.ExportProviderWithCSharpAndVisualBasic, languageServices, projectionBuffer, path, mappedCaretLocation, mappedSpans); this.ProjectionDocuments.Add(projectionDocument); return(projectionDocument); }
protected BaseProjectionBuffer(IProjectionEditResolver resolver, IContentType contentType, ITextDifferencingService textDifferencingService, GuardedOperations guardedOperations) : base(contentType, 0, textDifferencingService, guardedOperations) { this.resolver = resolver; // null is OK }
public IElisionBuffer CreateElisionBuffer(IProjectionEditResolver projectionEditResolver, NormalizedSnapshotSpanCollection exposedSpans, ElisionBufferOptions options) { return(CreateElisionBuffer(projectionEditResolver, exposedSpans, options, ProjectionContentType)); }