private void AddBraces( TaggerContext <BraceHighlightTag> context, ITextSnapshot snapshot, BraceMatchingResult?braces) { if (braces.HasValue) { context.AddTag(snapshot.GetTagSpan(braces.Value.LeftSpan.ToSpan(), BraceHighlightTag.StartTag)); context.AddTag(snapshot.GetTagSpan(braces.Value.RightSpan.ToSpan(), BraceHighlightTag.EndTag)); } }
private void ProduceTagsAsync(TaggerContext <TTag> context, DocumentSnapshotSpan spanToTag) { if (!_owner.IsEnabled) { return; } var document = spanToTag.Document; if (document == null) { return; } // Producing tags is simple. We just grab the diagnostics we were already told about, // and we convert them to tag spans. object id; ImmutableArray <DiagnosticData> diagnostics; SourceText sourceText; ITextSnapshot editorSnapshot; lock (_gate) { id = _latestId; diagnostics = _latestDiagnostics; sourceText = _latestSourceText; editorSnapshot = _latestEditorSnapshot; } if (sourceText == null || editorSnapshot == null) { return; } var project = document.Project; var requestedSnapshot = spanToTag.SnapshotSpan.Snapshot; var requestedSpan = spanToTag.SnapshotSpan; var isLiveUpdate = id is ISupportLiveUpdate; foreach (var diagnosticData in diagnostics) { if (_owner.IncludeDiagnostic(diagnosticData)) { var actualSpan = diagnosticData .GetExistingOrCalculatedTextSpan(sourceText) .ToSnapshotSpan(editorSnapshot) .TranslateTo(requestedSnapshot, SpanTrackingMode.EdgeExclusive); if (actualSpan.IntersectsWith(requestedSpan)) { var tagSpan = _owner.CreateTagSpan(isLiveUpdate, actualSpan, diagnosticData); if (tagSpan != null) { context.AddTag(tagSpan); } } } } }
private async Task AddTagSpansAsync( TaggerContext <NavigableHighlightTag> context, Solution solution, DocumentHighlights documentHighlights) { var cancellationToken = context.CancellationToken; var document = documentHighlights.Document; var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var textSnapshot = text.FindCorrespondingEditorTextSnapshot(); if (textSnapshot == null) { // There is no longer an editor snapshot for this document, so we can't care about the // results. return; } foreach (var span in documentHighlights.HighlightSpans) { var tag = GetTag(span); context.AddTag(new TagSpan <NavigableHighlightTag>( textSnapshot.GetSpan(Span.FromBounds(span.TextSpan.Start, span.TextSpan.End)), tag)); } }
protected override async Task ProduceTagsAsync(TaggerContext <IStructureTag> context, DocumentSnapshotSpan spanToTag, int?caretPosition) { var blockStructureProvider = spanToTag.Document.LanguageServices.GetService <IBlockStructureProvider>(); if (blockStructureProvider == null) { return; } var blockSpans = await blockStructureProvider.ProvideBlockStructureAsync(spanToTag.Document, context.CancellationToken).ConfigureAwait(false); var snapshot = spanToTag.SnapshotSpan.Snapshot; foreach (var blockSpan in blockSpans) { if (!blockSpan.IsCollapsible) { continue; } context.AddTag(snapshot.GetTagSpan( blockSpan.TextSpan.ToSpan(), new StructureTag( snapshot, blockSpan.TextSpan.ToSpan(), blockSpan.HintSpan.ToSpan(), isCollapsible: blockSpan.IsCollapsible, isDefaultCollapsed: blockSpan.IsDefaultCollapsed, type: GetStructureTagType(blockSpan.Type)))); } }
protected override async Task ProduceTagsAsync(TaggerContext <InlineParameterNameHintDataTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { var cancellationToken = context.CancellationToken; var document = documentSnapshotSpan.Document; var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var paramNameHintsService = document.GetLanguageService <IInlineParameterNameHintsService>(); if (paramNameHintsService != null) { var parameterHints = await paramNameHintsService.GetInlineParameterNameHintsAsync(document, snapshotSpan.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false); foreach (var parameterHint in parameterHints) { Contract.ThrowIfNull(parameterHint.Parameter); cancellationToken.ThrowIfCancellationRequested(); context.AddTag(new TagSpan <InlineParameterNameHintDataTag>( new SnapshotSpan(snapshotSpan.Snapshot, parameterHint.Position, 0), new InlineParameterNameHintDataTag( parameterHint.Parameter.GetSymbolKey(cancellationToken), parameterHint.Parameter.Name))); } } }
protected override async Task ProduceTagsAsync(TaggerContext <LineSeparatorTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { var cancellationToken = context.CancellationToken; var document = documentSnapshotSpan.Document; if (document == null) { return; } var options = document.Project.Solution.Workspace.Options; if (!options.GetOption(FeatureOnOffOptions.LineSeparator, document.Project.Language)) { return; } using (Logger.LogBlock(FunctionId.Tagger_LineSeparator_TagProducer_ProduceTags, cancellationToken)) { var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var lineSeparatorService = document.Project.LanguageServices.GetService <ILineSeparatorService>(); var lineSeparatorSpans = await lineSeparatorService.GetLineSeparatorsAsync(document, snapshotSpan.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); foreach (var span in lineSeparatorSpans) { context.AddTag(new TagSpan <LineSeparatorTag>(span.ToSnapshotSpan(snapshotSpan.Snapshot), LineSeparatorTag.Instance)); } } }
private void ProcessOutliningSpans( TaggerContext <IOutliningRegionTag> context, SnapshotSpan snapshotSpan, IOutliningService outliningService, IList <OutliningSpan> regions) { if (regions != null) { var snapshot = snapshotSpan.Snapshot; regions = GetMultiLineRegions(outliningService, regions, snapshot); // Create the outlining tags. var tagSpans = from region in regions let spanToCollapse = new SnapshotSpan(snapshot, region.TextSpan.ToSpan()) let hintSpan = new SnapshotSpan(snapshot, region.HintSpan.ToSpan()) let tag = new Tag(snapshot.TextBuffer, region.BannerText, hintSpan, region.AutoCollapse, region.IsDefaultCollapsed, _textEditorFactoryService, _projectionBufferFactoryService, _editorOptionsFactoryService) select new TagSpan <IOutliningRegionTag>(spanToCollapse, tag); foreach (var tagSpan in tagSpans) { context.AddTag(tagSpan); } } }
protected override async Task ProduceTagsAsync( TaggerContext <InlineHintDataTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition, CancellationToken cancellationToken) { var document = documentSnapshotSpan.Document; if (document == null) { return; } var service = document.GetLanguageService <IInlineHintsService>(); if (service == null) { return; } var options = GlobalOptions.GetInlineHintsOptions(document.Project.Language); var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var hints = await service.GetInlineHintsAsync(document, snapshotSpan.Span.ToTextSpan(), options, cancellationToken).ConfigureAwait(false); foreach (var hint in hints) { // If we don't have any text to actually show the user, then don't make a tag. if (hint.DisplayParts.Sum(p => p.ToString().Length) == 0) { continue; } context.AddTag(new TagSpan <InlineHintDataTag>( hint.Span.ToSnapshotSpan(snapshotSpan.Snapshot), new InlineHintDataTag(hint))); } }
private static void AddTagSpans( TaggerContext <NavigableHighlightTag> context, DocumentHighlights documentHighlights, CancellationToken cancellationToken) { var document = documentHighlights.Document; var textSnapshot = context.SpansToTag.FirstOrDefault(s => s.Document == document).SnapshotSpan.Snapshot; if (textSnapshot == null) { // There is no longer an editor snapshot for this document, so we can't care about the // results. return; } try { foreach (var span in documentHighlights.HighlightSpans) { var tag = GetTag(span); context.AddTag(new TagSpan <NavigableHighlightTag>( textSnapshot.GetSpan(Span.FromBounds(span.TextSpan.Start, span.TextSpan.End)), tag)); } } catch (Exception e) when(FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken, ErrorSeverity.General)) { // report NFW and continue. // also, rather than return partial results, return nothing context.ClearTags(); } }
protected override async Task ProduceTagsAsync(TaggerContext <IOutliningRegionTag> context, DocumentSnapshotSpan spanToTag, int?caretPosition) { var blockStructureProvider = spanToTag.Document.LanguageServices.GetService <IBlockStructureProvider>(); if (blockStructureProvider == null) { return; } var blockSpans = await blockStructureProvider.ProvideBlockStructureAsync(spanToTag.Document, context.CancellationToken).ConfigureAwait(false); var snapshot = spanToTag.SnapshotSpan.Snapshot; foreach (var blockSpan in blockSpans) { if (!blockSpan.IsCollapsible) { continue; } var collapsedHintForm = snapshot.GetText(blockSpan.HintSpan.ToSpan()); context.AddTag(snapshot.GetTagSpan( blockSpan.TextSpan.ToSpan(), new OutliningRegionTag(false, blockSpan.AutoCollapse, blockSpan.BannerText, collapsedHintForm))); } }
private static async Task AddTagSpansAsync( TaggerContext <NavigableHighlightTag> context, DocumentHighlights documentHighlights) { var cancellationToken = context.CancellationToken; var document = documentHighlights.Document; var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var textSnapshot = text.FindCorrespondingEditorTextSnapshot(); if (textSnapshot == null) { // There is no longer an editor snapshot for this document, so we can't care about the // results. return; } try { foreach (var span in documentHighlights.HighlightSpans) { var tag = GetTag(span); context.AddTag(new TagSpan <NavigableHighlightTag>( textSnapshot.GetSpan(Span.FromBounds(span.TextSpan.Start, span.TextSpan.End)), tag)); } } catch (Exception e) when(FatalError.ReportAndCatchUnlessCanceled(e)) { // report NFW and continue. // also, rather than return partial results, return nothing context.ClearTags(); } }
private void ProcessSpansWorker( TaggerContext <TRegionTag> context, SnapshotSpan snapshotSpan, BlockStructureService outliningService, ImmutableArray <BlockSpan> spans) { if (spans != null) { var snapshot = snapshotSpan.Snapshot; spans = GetMultiLineRegions(outliningService, spans, snapshot); // Create the outlining tags. var tagSpanStack = new Stack <TagSpan <TRegionTag> >(); foreach (var region in spans) { var spanToCollapse = new SnapshotSpan(snapshot, region.TextSpan.ToSpan()); while (tagSpanStack.Count > 0 && tagSpanStack.Peek().Span.End <= spanToCollapse.Span.Start) { tagSpanStack.Pop(); } var parentTag = tagSpanStack.Count > 0 ? tagSpanStack.Peek() : null; var tag = CreateTag(parentTag?.Tag, snapshot, region); var tagSpan = new TagSpan <TRegionTag>(spanToCollapse, tag); context.AddTag(tagSpan); tagSpanStack.Push(tagSpan); } } }
private async Task ProduceTagsForBracesAsync(TaggerContext <BraceHighlightTag> context, Document document, ITextSnapshot snapshot, int position, bool rightBrace) { if (position >= 0 && position <= snapshot.Length) { var braces = await _braceMatcherService.GetMatchingBracesAsync(document, position, context.CancellationToken).ConfigureAwait(false); if (braces.HasValue) { if ((!rightBrace && braces.Value.LeftSpan.Start == position) || (rightBrace && braces.Value.RightSpan.Start == position)) { context.AddTag(snapshot.GetTagSpan(braces.Value.LeftSpan.ToSpan(), BraceHighlightTag.StartTag)); context.AddTag(snapshot.GetTagSpan(braces.Value.RightSpan.ToSpan(), BraceHighlightTag.EndTag)); } } } }
protected override async Task ProduceTagsAsync(TaggerContext <KeywordHighlightTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { var cancellationToken = context.CancellationToken; var document = documentSnapshotSpan.Document; // https://devdiv.visualstudio.com/DevDiv/_workitems/edit/763988 // It turns out a document might be associated with a project of wrong language, e.g. C# document in a Xaml project. // Even though we couldn't repro the crash above, a fix is made in one of possibly multiple code paths that could cause // us to end up in this situation. // Regardless of the effective of the fix, we want to enhance the guard against such scenario here until an audit in // workspace is completed to eliminate the root cause. if (document?.SupportsSyntaxTree != true) { return; } var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); if (!documentOptions.GetOption(FeatureOnOffOptions.KeywordHighlighting)) { return; } if (!caretPosition.HasValue) { return; } var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var position = caretPosition.Value; var snapshot = snapshotSpan.Snapshot; // See if the user is just moving their caret around in an existing tag. If so, we don't // want to actually go recompute things. Note: this only works for containment. If the // user moves their caret to the end of a highlighted reference, we do want to recompute // as they may now be at the start of some other reference that should be highlighted instead. var existingTags = context.GetExistingContainingTags(new SnapshotPoint(snapshot, position)); if (!existingTags.IsEmpty()) { context.SetSpansTagged(SpecializedCollections.EmptyEnumerable <DocumentSnapshotSpan>()); return; } using (Logger.LogBlock(FunctionId.Tagger_Highlighter_TagProducer_ProduceTags, cancellationToken)) using (s_listPool.GetPooledObject(out var highlights)) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); _highlightingService.AddHighlights(root, position, highlights, cancellationToken); foreach (var span in highlights) { context.AddTag(new TagSpan <KeywordHighlightTag>(span.ToSnapshotSpan(snapshot), KeywordHighlightTag.Instance)); } } }
private void ProduceTags( TaggerContext <TTag> context, DocumentSnapshotSpan spanToTag, Workspace workspace, Document document, SourceText sourceText, NormalizedSnapshotSpanCollection suppressedDiagnosticsSpans, UpdatedEventArgs updateArgs, CancellationToken cancellationToken) { try { var id = updateArgs.Id; var diagnostics = _diagnosticService.GetDiagnostics( workspace, document.Project.Id, document.Id, id, false, cancellationToken); var isLiveUpdate = id is ISupportLiveUpdate; var requestedSpan = spanToTag.SnapshotSpan; var editorSnapshot = requestedSpan.Snapshot; foreach (var diagnosticData in diagnostics) { if (this.IncludeDiagnostic(diagnosticData)) { // We're going to be retrieving the diagnostics against the last time the engine // computed them against this document *id*. That might have been a different // version of the document vs what we're looking at now. But that's ok: // // 1) GetExistingOrCalculatedTextSpan will ensure that the diagnostics spans are // contained within 'editorSnapshot'. // 2) We'll eventually hear about an update to the diagnostics for this document // for whatever edits happened between the last time and this current snapshot. // So we'll eventually reach a point where the diagnostics exactly match the // editorSnapshot. var diagnosticSpan = diagnosticData.GetExistingOrCalculatedTextSpan(sourceText) .ToSnapshotSpan(editorSnapshot); if (diagnosticSpan.IntersectsWith(requestedSpan) && !IsSuppressed(suppressedDiagnosticsSpans, diagnosticSpan)) { var tagSpan = this.CreateTagSpan(isLiveUpdate, diagnosticSpan, diagnosticData); if (tagSpan != null) { context.AddTag(tagSpan); } } } } } catch (ArgumentOutOfRangeException ex) when(FatalError.ReportWithoutCrash(ex)) { // https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=428328&_a=edit&triage=false // explicitly report NFW to find out what is causing us for out of range. // stop crashing on such occations return; } }
protected override async Task ProduceTagsAsync( TaggerContext <StringIndentationTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition, CancellationToken cancellationToken) { var document = documentSnapshotSpan.Document; if (document == null) { return; } if (!GlobalOptions.GetOption(FeatureOnOffOptions.StringIdentation, document.Project.Language)) { return; } var service = document.GetLanguageService <IStringIndentationService>(); if (service == null) { return; } var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var regions = await service.GetStringIndentationRegionsAsync(document, snapshotSpan.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); if (regions.Length == 0) { return; } var snapshot = snapshotSpan.Snapshot; foreach (var region in regions) { var line = snapshot.GetLineFromPosition(region.IndentSpan.End); // If the indent is on the first column, then no need to actually show anything (plus we can't as we // want to draw one column earlier, and that column doesn't exist). if (line.Start == region.IndentSpan.End) { continue; } context.AddTag(new TagSpan <StringIndentationTag>( region.IndentSpan.ToSnapshotSpan(snapshot), new StringIndentationTag( _editorFormatMap, region.OrderedHoleSpans.SelectAsArray(s => s.ToSnapshotSpan(snapshot))))); } }
private async Task ProduceTagsAsync(TaggerContext <BraceHighlightTag> context, Document document, ITextSnapshot snapshot, int position) { var syntaxTree = await document.GetSyntaxTreeAsync(context.CancellationToken).ConfigureAwait(false); var braceMatcher = document.LanguageServices.GetService <IBraceMatcher>(); if (braceMatcher == null) { return; } var mappedPosition = syntaxTree.MapRootFilePosition(position); var result = braceMatcher.FindBraces(syntaxTree, mappedPosition, context.CancellationToken); if (result == null) { return; } context.AddTag(snapshot.GetTagSpan(result.Value.LeftSpan.ToSpan(), BraceHighlightTag.Tag)); context.AddTag(snapshot.GetTagSpan(result.Value.RightSpan.ToSpan(), BraceHighlightTag.Tag)); }
protected override async Task ProduceTagsAsync(TaggerContext <IOutliningRegionTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { try { var cancellationToken = context.CancellationToken; using (Logger.LogBlock(FunctionId.Tagger_Outlining_TagProducer_ProduceTags, cancellationToken)) { var document = documentSnapshotSpan.Document; var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var snapshot = snapshotSpan.Snapshot; if (document != null) { var outliningService = document.Project.LanguageServices.GetService <IOutliningService>(); if (outliningService != null) { var regions = await outliningService.GetOutliningSpansAsync(document, cancellationToken).ConfigureAwait(false); if (regions != null) { regions = GetMultiLineRegions(outliningService, regions, snapshotSpan.Snapshot); // Create the outlining tags. var tagSpans = from region in regions let spanToCollapse = new SnapshotSpan(snapshot, region.TextSpan.ToSpan()) let hintSpan = new SnapshotSpan(snapshot, region.HintSpan.ToSpan()) let tag = new Tag(snapshot.TextBuffer, region.BannerText, hintSpan, region.AutoCollapse, region.IsDefaultCollapsed, _textEditorFactoryService, _projectionBufferFactoryService, _editorOptionsFactoryService) select new TagSpan <IOutliningRegionTag>(spanToCollapse, tag); foreach (var tagSpan in tagSpans) { context.AddTag(tagSpan); } } } } } } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
protected override Task ProduceTagsAsync(TaggerContext <TestTag> context, DocumentSnapshotSpan snapshotSpan, int?caretPosition) { var tags = _callback(snapshotSpan.SnapshotSpan, context.CancellationToken); if (tags != null) { foreach (var tag in tags) { context.AddTag(tag); } } return(Task.CompletedTask); }
protected override async Task ProduceTagsAsync(TaggerContext <KeywordHighlightTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { var cancellationToken = context.CancellationToken; var document = documentSnapshotSpan.Document; if (document == null) { return; } var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); if (!documentOptions.GetOption(FeatureOnOffOptions.KeywordHighlighting)) { return; } if (!caretPosition.HasValue) { return; } var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var position = caretPosition.Value; var snapshot = snapshotSpan.Snapshot; // See if the user is just moving their caret around in an existing tag. If so, we don't // want to actually go recompute things. Note: this only works for containment. If the // user moves their caret to the end of a highlighted reference, we do want to recompute // as they may now be at the start of some other reference that should be highlighted instead. var existingTags = context.GetExistingContainingTags(new SnapshotPoint(snapshot, position)); if (!existingTags.IsEmpty()) { context.SetSpansTagged(SpecializedCollections.EmptyEnumerable <DocumentSnapshotSpan>()); return; } using (Logger.LogBlock(FunctionId.Tagger_Highlighter_TagProducer_ProduceTags, cancellationToken)) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var spans = _highlightingService.GetHighlights(root, position, cancellationToken); foreach (var span in spans) { context.AddTag(new TagSpan <KeywordHighlightTag>(span.ToSnapshotSpan(snapshot), KeywordHighlightTag.Instance)); } } }
protected override async Task ProduceTagsAsync(TaggerContext <KeywordHighlightTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { var cancellationToken = context.CancellationToken; var document = documentSnapshotSpan.Document; if (document == null) { return; } var options = document.Project.Solution.Workspace.Options; if (!options.GetOption(FeatureOnOffOptions.KeywordHighlighting, document.Project.Language)) { return; } if (!caretPosition.HasValue) { return; } var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var position = caretPosition.Value; var snapshot = snapshotSpan.Snapshot; var existingTags = context.GetExistingTags(new SnapshotSpan(snapshot, position, 0)); if (!existingTags.IsEmpty()) { // We already have a tag at this position. So the user is moving from one highlight // tag to another. In this case we don't want to recompute anything. Let our caller // know that we should preserve all tags. context.SetSpansTagged(SpecializedCollections.EmptyEnumerable <DocumentSnapshotSpan>()); return; } using (Logger.LogBlock(FunctionId.Tagger_Highlighter_TagProducer_ProduceTags, cancellationToken)) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var spans = _highlightingService.GetHighlights(root, position, cancellationToken); foreach (var span in spans) { context.AddTag(new TagSpan <KeywordHighlightTag>(span.ToSnapshotSpan(snapshot), KeywordHighlightTag.Instance)); } } }
private void ProcessSpans( TaggerContext <IStructureTag> context, SnapshotSpan snapshotSpan, BlockStructureService outliningService, ImmutableArray <BlockSpan> spans) { var snapshot = snapshotSpan.Snapshot; spans = GetMultiLineRegions(outliningService, spans, snapshot); foreach (var span in spans) { var tag = new StructureTag(this, span, snapshot); context.AddTag(new TagSpan <IStructureTag>(span.TextSpan.ToSnapshotSpan(snapshot), tag)); } }
protected override async Task ProduceTagsAsync(TaggerContext <ITextMarkerTag> context) { Debug.Assert(context.SpansToTag.IsSingle()); var spanToTag = context.SpansToTag.Single(); var document = spanToTag.Document; if (document == null) { return; } var activeStatementTrackingService = document.Project.Solution.Workspace.Services.GetService <IActiveStatementTrackingService>(); if (activeStatementTrackingService == null) { return; } var snapshot = spanToTag.SnapshotSpan.Snapshot; var activeStatementSpans = await activeStatementTrackingService .GetAdjustedTrackingSpansAsync(document, snapshot, context.CancellationToken) .ConfigureAwait(false); foreach (var activeStatementSpan in activeStatementSpans) { if (activeStatementSpan.IsLeaf) { continue; } var snapshotSpan = activeStatementSpan.Span.GetSpan(snapshot); if (snapshotSpan.OverlapsWith(spanToTag.SnapshotSpan)) { context.AddTag( new TagSpan <ITextMarkerTag>(snapshotSpan, ActiveStatementTag.Instance) ); } } // Let the context know that this was the span we actually tried to tag. context.SetSpansTagged(SpecializedCollections.SingletonEnumerable(spanToTag)); }
protected override async Task ProduceTagsAsync( TaggerContext <LineSeparatorTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition, CancellationToken cancellationToken) { var document = documentSnapshotSpan.Document; if (document == null) { return; } if (!GlobalOptions.GetOption(FeatureOnOffOptions.LineSeparator, document.Project.Language)) { return; } using (Logger.LogBlock(FunctionId.Tagger_LineSeparator_TagProducer_ProduceTags, cancellationToken)) { var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var lineSeparatorService = document.GetLanguageService <ILineSeparatorService>(); if (lineSeparatorService == null) { return; } var lineSeparatorSpans = await lineSeparatorService.GetLineSeparatorsAsync(document, snapshotSpan.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); if (lineSeparatorSpans.Length == 0) { return; } LineSeparatorTag tag; lock (_lineSeperatorTagGate) { tag = _lineSeparatorTag; } foreach (var span in lineSeparatorSpans) { context.AddTag(new TagSpan <LineSeparatorTag>(span.ToSnapshotSpan(snapshotSpan.Snapshot), tag)); } } }
private static async Task ClassifySpansAsync( TaggerContext <IClassificationTag> context, DocumentSnapshotSpan spanToTag, IClassificationService classificationService, ClassificationTypeMap typeMap, ClassificationOptions options, CancellationToken cancellationToken) { try { var document = spanToTag.Document; var snapshotSpan = spanToTag.SnapshotSpan; var snapshot = snapshotSpan.Snapshot; using (Logger.LogBlock(FunctionId.Tagger_SemanticClassification_TagProducer_ProduceTags, cancellationToken)) { using var _ = ArrayBuilder <ClassifiedSpan> .GetInstance(out var classifiedSpans); await classificationService.AddSemanticClassificationsAsync( document, snapshotSpan.Span.ToTextSpan(), options, classifiedSpans, cancellationToken).ConfigureAwait(false); foreach (var span in classifiedSpans) { context.AddTag(ClassificationUtilities.Convert(typeMap, snapshotSpan.Snapshot, span)); } var version = await document.Project.GetDependentSemanticVersionAsync(cancellationToken).ConfigureAwait(false); // Let the context know that this was the span we actually tried to tag. context.SetSpansTagged(SpecializedCollections.SingletonEnumerable(spanToTag)); context.State = version; } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; } }
private static void AddDiagnostics(TaggerContext <IErrorTag> context, IEnumerable <MappedDiagnostic> mappedDiagnostics, ITextSnapshot snapshot) { foreach (var mappedDiagnostic in mappedDiagnostics) { context.CancellationToken.ThrowIfCancellationRequested(); if (!mappedDiagnostic.FileSpan.IsInRootFile) { continue; } var errorType = mappedDiagnostic.Diagnostic.Severity == DiagnosticSeverity.Warning ? PredefinedErrorTypeNames.Warning : (mappedDiagnostic.Source == DiagnosticSource.SyntaxParsing ? PredefinedErrorTypeNames.SyntaxError : PredefinedErrorTypeNames.CompilerError); var tag = new ErrorTag(errorType, mappedDiagnostic.Diagnostic.Message); context.AddTag(snapshot.GetTagSpan(mappedDiagnostic.FileSpan.Span.ToSpan(), tag)); } }
protected override async Task ProduceTagsAsync(TaggerContext <InlineHintDataTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { var cancellationToken = context.CancellationToken; var document = documentSnapshotSpan.Document; var service = document.GetLanguageService <IInlineHintsService>(); if (service == null) { return; } var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var hints = await service.GetInlineHintsAsync(document, snapshotSpan.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false); foreach (var hint in hints) { context.AddTag(new TagSpan <InlineHintDataTag>( hint.Span.ToSnapshotSpan(snapshotSpan.Snapshot), new InlineHintDataTag(hint))); } }
private void AddTagSpans( TaggerContext <NavigableHighlightTag> context, DocumentHighlights documentHighlights) { var cancellationToken = context.CancellationToken; var document = documentHighlights.Document; var text = document.SourceText; var textSnapshot = text.FindCorrespondingEditorTextSnapshot(); if (textSnapshot == null) { // There is no longer an editor snapshot for this document, so we can't care about the // results. return; } foreach (var span in documentHighlights.HighlightSpans) { var tag = GetTag(span); context.AddTag(new TagSpan <NavigableHighlightTag>( textSnapshot.GetSpan(Span.FromBounds(span.TextSpan.Start, span.TextSpan.End)), tag)); } }
protected override async Task ProduceTagsAsync( TaggerContext <InheritanceMarginTag> context, DocumentSnapshotSpan spanToTag, int?caretPosition, CancellationToken cancellationToken) { var document = spanToTag.Document; if (document == null) { return; } var inheritanceMarginInfoService = document.GetLanguageService <IInheritanceMarginService>(); if (inheritanceMarginInfoService == null) { return; } if (GlobalOptions.GetOption(FeatureOnOffOptions.ShowInheritanceMargin, document.Project.Language) == false) { return; } var includeGlobalImports = GlobalOptions.GetOption(FeatureOnOffOptions.InheritanceMarginIncludeGlobalImports, document.Project.Language); // Use FrozenSemantics Version of document to get the semantics ready, therefore we could have faster // response. (Since the full load might take a long time) // We also subscribe to CompilationAvailableTaggerEventSource, so this will finally reach the correct state. document = document.WithFrozenPartialSemantics(cancellationToken); var spanToSearch = spanToTag.SnapshotSpan.Span.ToTextSpan(); var stopwatch = SharedStopwatch.StartNew(); var inheritanceMemberItems = await inheritanceMarginInfoService.GetInheritanceMemberItemsAsync( document, spanToSearch, includeGlobalImports, cancellationToken).ConfigureAwait(false); var elapsed = stopwatch.Elapsed; if (inheritanceMemberItems.IsEmpty) { return; } InheritanceMarginLogger.LogGenerateBackgroundInheritanceInfo(elapsed); // One line might have multiple members to show, so group them. // For example: // interface IBar { void Foo1(); void Foo2(); } // class Bar : IBar { void Foo1() { } void Foo2() { } } var lineToMembers = inheritanceMemberItems.GroupBy(item => item.LineNumber); var snapshot = spanToTag.SnapshotSpan.Snapshot; foreach (var(lineNumber, membersOnTheLine) in lineToMembers) { var membersOnTheLineArray = membersOnTheLine.ToImmutableArray(); // One line should at least have one member on it. Contract.ThrowIfTrue(membersOnTheLineArray.IsEmpty); var line = snapshot.GetLineFromLineNumber(lineNumber); // We only care about the line, so just tag the start. context.AddTag(new TagSpan <InheritanceMarginTag>( new SnapshotSpan(snapshot, line.Start, length: 0), new InheritanceMarginTag(document.Project.Solution.Workspace, lineNumber, membersOnTheLineArray))); } }
private void ProduceTags(TaggerContext <TTag> context, DocumentSnapshotSpan spanToTag) { try { if (!_owner.IsEnabled) { return; } var document = spanToTag.Document; if (document == null) { return; } // See if we've marked any spans as those we want to suppress diagnostics for. // This can happen for buffers used in the preview workspace where some feature // is generating code that it doesn't want errors shown for. var buffer = spanToTag.SnapshotSpan.Snapshot.TextBuffer; var suppressedDiagnosticsSpans = default(NormalizedSnapshotSpanCollection); buffer?.Properties.TryGetProperty(PredefinedPreviewTaggerKeys.SuppressDiagnosticsSpansKey, out suppressedDiagnosticsSpans); // Producing tags is simple. We just grab the diagnostics we were already told about, // and we convert them to tag spans. object id; ImmutableArray <DiagnosticData> diagnostics; SourceText sourceText; ITextSnapshot editorSnapshot; lock (_gate) { id = _latestId; diagnostics = _latestDiagnostics; sourceText = _latestSourceText; editorSnapshot = _latestEditorSnapshot; } if (sourceText == null || editorSnapshot == null) { return; } var project = document.Project; var requestedSnapshot = spanToTag.SnapshotSpan.Snapshot; var requestedSpan = spanToTag.SnapshotSpan; var isLiveUpdate = id is ISupportLiveUpdate; foreach (var diagnosticData in diagnostics) { if (_owner.IncludeDiagnostic(diagnosticData)) { var actualSpan = diagnosticData .GetExistingOrCalculatedTextSpan(sourceText) .ToSnapshotSpan(editorSnapshot) .TranslateTo(requestedSnapshot, SpanTrackingMode.EdgeExclusive); if (actualSpan.IntersectsWith(requestedSpan) && !IsSuppressed(suppressedDiagnosticsSpans, actualSpan)) { var tagSpan = _owner.CreateTagSpan(isLiveUpdate, actualSpan, diagnosticData); if (tagSpan != null) { context.AddTag(tagSpan); } } } } } catch (ArgumentOutOfRangeException ex) when(FatalError.ReportWithoutCrash(ex)) { // https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=428328&_a=edit&triage=false // explicitly report NFW to find out what is causing us for out of range. // stop crashing on such occations return; } }