internal static IList<ITagSpan<IErrorTag>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();

            var listener = new AsynchronousOperationListener();
            var listeners = AsynchronousOperationListener.CreateListeners(
                ValueTuple.Create(FeatureAttribute.DiagnosticService, listener),
                ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener));

            var optionsService = workspace.Services.GetService<IOptionService>();
            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(source), listeners);

            var foregroundService = workspace.GetService<IForegroundNotificationService>();  //new TestForegroundNotificationService();

            var buffer = document.GetTextBuffer();
            var provider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners);
            var tagger = provider.CreateTagger<IErrorTag>(buffer);

            source.RaiseDiagnosticsUpdated(updateArgs);

            listener.CreateWaitTask().PumpingWait();

            var snapshot = buffer.CurrentSnapshot;
            var spans = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToImmutableArray();

            ((IDisposable)tagger).Dispose();

            return spans;
        }
        internal static IList<ITagSpan<IErrorTag>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();

            var diagnosticWaiter = new DiagnosticServiceWaiter();
            var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy<IAsynchronousOperationListener, FeatureMetadata>(
                () => diagnosticWaiter, new FeatureMetadata(new Dictionary<string, object>() { { "FeatureName", FeatureAttribute.DiagnosticService } })));

            var optionsService = workspace.Services.GetService<IOptionService>();
            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(source), diagnosticListeners);

            var squiggleWaiter = new ErrorSquiggleWaiter();
            var foregroundService = new TestForegroundNotificationService();

            var buffer = document.GetTextBuffer();
            var taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);

            source.RaiseDiagnosticsUpdated(updateArgs);

            diagnosticWaiter.CreateWaitTask().PumpingWait();
            squiggleWaiter.CreateWaitTask().PumpingWait();

            var snapshot = buffer.CurrentSnapshot;
            var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer);
            var spans = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length));

            taggerSource.TestOnly_Dispose();

            return spans;
        }
 protected void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs args)
 {
     var updated = this.DiagnosticsUpdated;
     if (updated != null)
     {
         updated(this, args);
     }
 }
 internal void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs state)
 {
     var handler = this.DiagnosticsUpdated;
     if (handler != null)
     {
         handler(this, state);
     }
 }
 internal void RaiseDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs state)
 {
     var handler = this.DiagnosticsUpdated;
     if (handler != null)
     {
         handler(sender, state);
     }
 }
            private void OnDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs e)
            {
                var document = _subjectBuffer.AsTextContainer().GetOpenDocumentInCurrentContext();

                if (document != null && document.Project.Solution.Workspace == e.Workspace && document.Id == e.DocumentId)
                {
                    this.RaiseChanged();
                }
            }
 internal void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs args)
 {
     // all diagnostics events are serialized.
     var ev = _eventMap.GetEventHandlers<EventHandler<DiagnosticsUpdatedArgs>>(DiagnosticsUpdatedEventName);
     if (ev.HasHandlers)
     {
         var asyncToken = Listener.BeginAsyncOperation(nameof(RaiseDiagnosticsUpdated));
         _eventQueue.ScheduleTask(() => ev.RaiseEvent(handler => handler(this, args))).CompletesAsyncOperation(asyncToken);
     }
 }
        private void RaiseDiagnosticsUpdatedForProject(ProjectId projectId, object key, IEnumerable<DiagnosticData> items)
        {
            var args = new DiagnosticsUpdatedArgs(
                id: Tuple.Create(this, projectId, key),
                workspace: _workspace,
                solution: null,
                projectId: projectId,
                documentId: null,
                diagnostics: items.AsImmutableOrEmpty());

            RaiseDiagnosticsUpdated(args);
        }
        internal static async Task<IList<ITagSpan<IErrorTag>>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();
            using (var wrapper = new DiagnosticTaggerWrapper(workspace, source))
            {
                var tagger = wrapper.TaggerProvider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer());
                using (var disposable = tagger as IDisposable)
                {
                    source.RaiseDiagnosticsUpdated(updateArgs);

                    await wrapper.WaitForTags();

                    var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
                    var spans = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToImmutableArray();

                    return spans;
                }
            }
        }
Beispiel #10
0
            public void OnAnalyzerLoadFailed(object?sender, AnalyzerLoadFailureEventArgs e)
            {
                if (!(sender is AnalyzerFileReference reference))
                {
                    return;
                }

                var diagnostic = AnalyzerHelper.CreateAnalyzerLoadFailureDiagnostic(e, reference.FullPath, projectId: null, language: null);

                // diagnostic from host analyzer can never go away
                var args = DiagnosticsUpdatedArgs.DiagnosticsCreated(
                    id: Tuple.Create(this, reference.FullPath, e.ErrorCode, e.TypeName),
                    workspace: _primaryWorkspace.Workspace,
                    solution: null,
                    projectId: null,
                    documentId: null,
                    diagnostics: ImmutableArray.Create <DiagnosticData>(diagnostic));

                // this can be null in test. but in product code, this should never be null.
                _hostUpdateSource?.RaiseDiagnosticsUpdated(args);
            }
            public async Task AnalyzeSyntaxAsync(Document document, InvocationReasons reasons, CancellationToken cancellationToken)
            {
                // right now, there is no way to observe diagnostics for closed file.
                if (!_workspace.IsDocumentOpen(document.Id) ||
                    !_workspace.Options.GetOption(InternalRuntimeDiagnosticOptions.Syntax))
                {
                    return;
                }

                var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                var diagnostics = tree.GetDiagnostics(cancellationToken);

                Contract.Requires(document.Project.Solution.Workspace == _workspace);

                var diagnosticData = diagnostics == null ? ImmutableArray <DiagnosticData> .Empty : diagnostics.Select(d => DiagnosticData.Create(document, d)).ToImmutableArrayOrEmpty();

                _service.RaiseDiagnosticsUpdated(
                    DiagnosticsUpdatedArgs.DiagnosticsCreated(new DefaultUpdateArgsId(_workspace.Kind, Syntax, document.Id),
                                                              _workspace, document.Project.Solution, document.Project.Id, document.Id, diagnosticData));
            }
Beispiel #12
0
        private void RaiseDiagnosticsUpdated(IDiagnosticUpdateSource source, DiagnosticsUpdatedArgs args)
        {
            var ev = _eventMap.GetEventHandlers <EventHandler <DiagnosticsUpdatedArgs> >(DiagnosticsUpdatedEventName);

            if (!RequireRunningEventTasks(source, ev))
            {
                return;
            }

            var eventToken = _listener.BeginAsyncOperation(DiagnosticsUpdatedEventName);

            _eventQueue.ScheduleTask(() =>
            {
                if (!UpdateDataMap(source, args))
                {
                    // there is no change, nothing to raise events for.
                    return;
                }

                ev.RaiseEvent(handler => handler(source, args));
            }).CompletesAsyncOperation(eventToken);
        }
            private async Task AnalyzeForKind(Document document, AnalysisKind kind, CancellationToken cancellationToken)
            {
                var diagnosticData = await _service._analyzerService.GetDiagnosticsAsync(document, GetAnalyzers(), kind, cancellationToken).ConfigureAwait(false);

                _service.RaiseDiagnosticsUpdated(
                    DiagnosticsUpdatedArgs.DiagnosticsCreated(new DefaultUpdateArgsId(_workspace.Kind, kind, document.Id),
                                                              _workspace, document.Project.Solution, document.Project.Id, document.Id, diagnosticData.ToImmutableArrayOrEmpty()));

                IEnumerable <DiagnosticAnalyzer> GetAnalyzers()
                {
                    // C# or VB document that supports compiler
                    var compilerAnalyzer = _service._analyzerService.GetCompilerDiagnosticAnalyzer(document.Project.Language);

                    if (compilerAnalyzer != null)
                    {
                        return(SpecializedCollections.SingletonEnumerable(compilerAnalyzer));
                    }

                    // document that doesn't support compiler diagnostics such as fsharp or typescript
                    return(_service._analyzerService.GetDiagnosticAnalyzers(document.Project));
                }
            }
Beispiel #14
0
            public void OnAnalyzerLoadFailed(object sender, AnalyzerLoadFailureEventArgs e)
            {
                var reference = sender as AnalyzerFileReference;

                if (reference == null)
                {
                    return;
                }

                var diagnostic = AnalyzerHelper.CreateAnalyzerLoadFailureDiagnostic(reference.FullPath, e);

                // diagnostic from host analyzer can never go away
                var args = DiagnosticsUpdatedArgs.DiagnosticsCreated(
                    id: Tuple.Create(this, reference.FullPath, e.ErrorCode, e.TypeName),
                    workspace: PrimaryWorkspace.Workspace,
                    solution: null,
                    projectId: null,
                    documentId: null,
                    diagnostics: ImmutableArray.Create <DiagnosticData>(diagnostic));

                _hostUpdateSource.RaiseDiagnosticsUpdated(args);
            }
Beispiel #15
0
            public async Task AnalyzeDocumentAsync(Document document, SyntaxNode bodyOpt, InvocationReasons reasons, CancellationToken cancellationToken)
            {
                // right now, there is no way to observe diagnostics for closed file.
                if (!_workspace.IsDocumentOpen(document.Id) ||
                    !_workspace.Options.GetOption(InternalRuntimeDiagnosticOptions.Semantic))
                {
                    return;
                }

                var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                var diagnostics = model.GetMethodBodyDiagnostics(span: null, cancellationToken: cancellationToken).Concat(
                    model.GetDeclarationDiagnostics(span: null, cancellationToken: cancellationToken));

                Debug.Assert(document.Project.Solution.Workspace == _workspace);

                var diagnosticData = diagnostics == null ? ImmutableArray <DiagnosticData> .Empty : diagnostics.Select(d => DiagnosticData.Create(document, d)).ToImmutableArrayOrEmpty();

                _service.RaiseDiagnosticsUpdated(
                    DiagnosticsUpdatedArgs.DiagnosticsCreated(new DefaultUpdateArgsId(_workspace.Kind, Semantic, document.Id),
                                                              _workspace, document.Project.Solution, document.Project.Id, document.Id, diagnosticData));
            }
Beispiel #16
0
        private bool ClearDiagnosticsReportedBySource(
            IDiagnosticUpdateSource source,
            List <DiagnosticsUpdatedArgs> removed
            )
        {
            // we expect source who uses this ability to have small number of diagnostics.
            lock (_gate)
            {
                Debug.Assert(_updateSources.Contains(source));

                // 2 different workspaces (ex, PreviewWorkspaces) can return same Args.Id, we need to
                // distinguish them. so we separate diagnostics per workspace map.
                if (!_map.TryGetValue(source, out var workspaceMap))
                {
                    return(false);
                }

                foreach (var(workspace, map) in workspaceMap)
                {
                    foreach (var(id, data) in map)
                    {
                        removed.Add(
                            DiagnosticsUpdatedArgs.DiagnosticsRemoved(
                                id,
                                data.Workspace,
                                solution: null,
                                data.ProjectId,
                                data.DocumentId
                                )
                            );
                    }
                }

                // all diagnostics from the source is cleared
                _map.Remove(source);
                return(true);
            }
        }
 public void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs args)
 {
     this.DiagnosticsUpdated?.Invoke(this, args);
 }
 private void RaiseEmptyDiagnosticUpdated(AnalysisKind kind, DocumentId documentId)
 {
     _service.RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs.DiagnosticsRemoved(
                                          new DefaultUpdateArgsId(_workspace.Kind, kind, documentId), _workspace, null, documentId.ProjectId, documentId));
 }
 private DiagnosticsUpdatedArgs MakeCreatedArgs(DiagnosticAnalyzer analyzer, ImmutableHashSet <DiagnosticData> items, Project project)
 {
     return(DiagnosticsUpdatedArgs.DiagnosticsCreated(
                CreateId(analyzer, project), this.Workspace, project?.Solution, project?.Id, documentId: null, diagnostics: items.ToImmutableArray()));
 }
 private DiagnosticsUpdatedArgs MakeRemovedArgs(DiagnosticAnalyzer analyzer, Project project)
 {
     return(DiagnosticsUpdatedArgs.DiagnosticsRemoved(
                CreateId(analyzer, project), this.Workspace, project?.Solution, project?.Id, documentId: null));
 }
 public void RaiseUpdateEvent(DiagnosticsUpdatedArgs args)
 {
     DiagnosticsUpdated?.Invoke(this, args);
 }
        public void LiveErrorZeroLengthSpan()
        {
            var workspaceXml =
@"<Workspace>
    <Project Language=""C#"" CommonReferences=""true"">
        <Document FilePath = ""Test.cs"" >
            class Test
{
}
        </Document>
    </Project>
</Workspace>";

            using (var workspace = TestWorkspaceFactory.CreateWorkspace(workspaceXml))
            {
                var document = workspace.Documents.First();

                var updateArgs = new DiagnosticsUpdatedArgs(
                        new LiveId(), workspace, workspace.CurrentSolution, document.Project.Id, document.Id,
                        ImmutableArray.Create(
                            CreateDiagnosticData(workspace, document, new TextSpan(0, 0)),
                            CreateDiagnosticData(workspace, document, new TextSpan(0, 1))));

                var spans = GetErrorsFromUpdateSource(workspace, document, updateArgs);

                Assert.Equal(2, spans.Count());
                var first = spans.First();
                var second = spans.Last();

                Assert.Equal(1, first.Span.Span.Length);
                Assert.Equal(1, second.Span.Span.Length);
            }
        }
 public void RaiseUpdateEvent(DiagnosticsUpdatedArgs args)
 {
     var handler = DiagnosticsUpdated;
     if (handler != null)
     {
         handler(this, args);
     }
 }
Beispiel #24
0
        private bool UpdateDataMap(IDiagnosticUpdateSource source, DiagnosticsUpdatedArgs args)
        {
            // we expect source who uses this ability to have small number of diagnostics.
            lock (_gate)
            {
                Debug.Assert(_updateSources.Contains(source));

                // The diagnostic service itself caches all diagnostics produced by the IDiagnosticUpdateSource's.  As
                // such, we want to grab all the diagnostics (regardless of push/pull setting) and cache inside
                // ourselves.  Later, when anyone calls GetDiagnostics or GetDiagnosticBuckets we will check if their
                // push/pull request matches the current user setting and return these if appropriate.
                var diagnostics = args.GetAllDiagnosticsRegardlessOfPushPullSetting();

                // check cheap early bail out
                if (diagnostics.Length == 0 && !_map.ContainsKey(source))
                {
                    // no new diagnostic, and we don't have update source for it.
                    return(false);
                }

                // 2 different workspaces (ex, PreviewWorkspaces) can return same Args.Id, we need to
                // distinguish them. so we separate diagnostics per workspace map.
                var workspaceMap = _map.GetOrAdd(
                    source,
                    _ => new Dictionary <Workspace, Dictionary <object, Data> >()
                    );

                if (diagnostics.Length == 0 && !workspaceMap.ContainsKey(args.Workspace))
                {
                    // no new diagnostic, and we don't have workspace for it.
                    return(false);
                }

                var diagnosticDataMap = workspaceMap.GetOrAdd(
                    args.Workspace,
                    _ => new Dictionary <object, Data>()
                    );

                diagnosticDataMap.Remove(args.Id);
                if (diagnosticDataMap.Count == 0 && diagnostics.Length == 0)
                {
                    workspaceMap.Remove(args.Workspace);

                    if (workspaceMap.Count == 0)
                    {
                        _map.Remove(source);
                    }

                    return(true);
                }

                if (diagnostics.Length > 0)
                {
                    // save data only if there is a diagnostic
                    var data = source.SupportGetDiagnostics
                        ? new Data(args)
                        : new Data(args, diagnostics);
                    diagnosticDataMap.Add(args.Id, data);
                }

                return(true);
            }
        }
Beispiel #25
0
            public void OnAnalyzerLoadFailed(object sender, AnalyzerLoadFailureEventArgs e)
            {
                var reference = sender as AnalyzerFileReference;
                if (reference == null)
                {
                    return;
                }

                var diagnostic = AnalyzerHelper.CreateAnalyzerLoadFailureDiagnostic(reference.FullPath, e);

                // diagnostic from host analyzer can never go away
                var args = new DiagnosticsUpdatedArgs(
                    id: Tuple.Create(this, reference.FullPath, e.ErrorCode, e.TypeName),
                    workspace: PrimaryWorkspace.Workspace,
                    solution: null,
                    projectId: null,
                    documentId: null,
                    diagnostics: ImmutableArray.Create<DiagnosticData>(diagnostic));

                _hostUpdateSource.RaiseDiagnosticsUpdated(args);
            }
            private void OnDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs e)
            {
                // document removed case. no reason to raise event
                if (e.Solution == null)
                {
                    return;
                }

                OnSuggestedActionsChanged(e.Workspace, e.DocumentId, e.Solution.WorkspaceVersion);
            }
 public void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs args)
 {
     this.DiagnosticsUpdated?.Invoke(this, args);
 }
Beispiel #28
0
 private void OnDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs e)
 {
     RaiseDiagnosticsUpdated(sender, e);
 }
Beispiel #29
0
 private void OnDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs e)
 {
     AssertIfNull(e.Diagnostics);
     RaiseDiagnosticsUpdated(sender, e);
 }
 internal void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs state)
 => DiagnosticsUpdated?.Invoke(this, state);
 internal void RaiseDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs state)
 {
     this.DiagnosticsUpdated?.Invoke(sender, state);
 }
            private void OnSuggestedActionsChanged(Workspace currentWorkspace, DocumentId currentDocumentId, int solutionVersion, DiagnosticsUpdatedArgs args = null)
            {
                // Explicitly hold onto the _subjectBuffer field in a local and use this local in this function to avoid crashes
                // if this field happens to be cleared by Dispose() below. This is required since this code path involves code
                // that can run on background thread.
                var buffer = _subjectBuffer;
                if (buffer == null)
                {
                    return;
                }

                var workspace = buffer.GetWorkspace();

                // workspace is not ready, nothing to do.
                if (workspace == null || workspace != currentWorkspace)
                {
                    return;
                }

                if (currentDocumentId != workspace.GetDocumentIdInCurrentContext(buffer.AsTextContainer()) ||
                    solutionVersion == Volatile.Read(ref _lastSolutionVersionReported))
                {
                    return;
                }
                this.SuggestedActionsChanged?.Invoke(this, EventArgs.Empty);

                Volatile.Write(ref _lastSolutionVersionReported, solutionVersion);
            }
            private void OnSuggestedActionsChanged(Workspace currentWorkspace, DocumentId currentDocumentId, int solutionVersion, DiagnosticsUpdatedArgs args = null)
            {
                if (_subjectBuffer == null)
                {
                    return;
                }

                var workspace = _subjectBuffer.GetWorkspace();

                // workspace is not ready, nothing to do.
                if (workspace == null || workspace != currentWorkspace)
                {
                    return;
                }

                if (currentDocumentId != workspace.GetDocumentIdInCurrentContext(_subjectBuffer.AsTextContainer()) ||
                    solutionVersion == Volatile.Read(ref _lastSolutionVersionReported))
                {
                    return;
                }

                // make sure we only raise event once for same solution version.
                // light bulb controller will call us back to find out new information
                var changed = this.SuggestedActionsChanged;
                if (changed != null)
                {
                    changed(this, EventArgs.Empty);
                }

                Volatile.Write(ref _lastSolutionVersionReported, solutionVersion);
            }