Ejemplo n.º 1
0
        async void OnDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs e)
        {
            if (!enabled)
            {
                return;
            }

            var doc = DocumentContext.ParsedDocument;

            if (doc == null || DocumentContext.IsAdHocProject)
            {
                return;
            }

            if (DocumentContext.AnalysisDocument == null)
            {
                return;
            }

            if (e.DocumentId != DocumentContext.AnalysisDocument.Id || e.ProjectId != DocumentContext.AnalysisDocument.Project.Id)
            {
                return;
            }

            var token = CancelUpdateTimeout(e.Id);
            var ad    = new AnalysisDocument(Editor, DocumentContext);

            try {
                var result = await CodeDiagnosticRunner.Check(ad, token, e.Diagnostics).ConfigureAwait(false);

                var updater = new ResultsUpdater(this, result, e.Id, token);
                updater.Update();
            } catch (Exception) {
            }
        }
Ejemplo n.º 2
0
        async void OnDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs e)
        {
            if (!enabled)
            {
                return;
            }

            var doc = DocumentContext.ParsedDocument;

            if (doc == null || DocumentContext.IsAdHocProject)
            {
                return;
            }

            var cad = DocumentContext.AnalysisDocument;

            if (cad == null || cad.Project == null)
            {
                return;
            }

            if (e.DocumentId != cad.Id || e.ProjectId != cad.Project.Id)
            {
                return;
            }
            var token = CancelUpdateTimeout(e.Id);
            var ad    = new AnalysisDocument(Editor, DocumentContext);

            try {
                var result = await CodeDiagnosticRunner.Check(ad, token, e.Diagnostics).ConfigureAwait(false);

                if (result is IReadOnlyList <Result> resultList)
                {
                    await Runtime.RunInMainThread(delegate {
                        if (resultUpdaters.TryGetValue(e.Id, out var oldUpdater))
                        {
                            oldUpdater.Cancel();
                        }
                        var updater = new ResultsUpdater(this, resultList, e.Id);
                        updater.Start();
                        resultUpdaters [e.Id] = updater;
                    });
                }
Ejemplo n.º 3
0
        void OnDocumentParsed(object sender, EventArgs args)
        {
            if (!AnalysisOptions.EnableFancyFeatures)
            {
                return;
            }
            CancelUpdateTimout();
            var doc = DocumentContext.ParsedDocument;

            if (doc == null)
            {
                return;
            }
            updateTimeout = GLib.Timeout.Add(250, delegate {
                lock (updateLock) {
                    CancelTask();
                    src       = new CancellationTokenSource();
                    var token = src.Token;
                    var ad    = new AnalysisDocument(Editor, DocumentContext);
                    oldTask   = Task.Run(() => {
                        try {
                            var result = CodeDiagnosticRunner.Check(ad, token);
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }
                            var updater = new ResultsUpdater(this, result, token);
                            updater.Update();
                        } catch (OperationCanceledException) {
                        } catch (AggregateException) {
                        }
                    });
                    updateTimeout = 0;
                    return(false);
                }
            });
        }
Ejemplo n.º 4
0
        internal Task <CodeActionContainer> GetCurrentFixesAsync(CancellationToken cancellationToken)
        {
            var loc = Editor.CaretOffset;
            var ad  = DocumentContext.AnalysisDocument;

            if (ad == null)
            {
                return(Task.FromResult(CodeActionContainer.Empty));
            }
            TextSpan span;

            if (Editor.IsSomethingSelected)
            {
                var selectionRange = Editor.SelectionRange;
                span = selectionRange.Offset >= 0 ? TextSpan.FromBounds(selectionRange.Offset, selectionRange.EndOffset) : TextSpan.FromBounds(loc, loc);
            }
            else
            {
                span = TextSpan.FromBounds(loc, loc);
            }
            var rExt      = Editor.GetContent <ResultsEditorExtension> ();
            var errorList = Editor
                            .GetTextSegmentMarkersAt(Editor.CaretOffset)
                            .OfType <IErrorMarker> ()
                            .Where(rm => !string.IsNullOrEmpty(rm.Error.Id)).ToList();

            return(Task.Run(async delegate {
                try {
                    var result = await CodeDiagnosticRunner.Check(new AnalysisDocument(Editor, DocumentContext), cancellationToken).ConfigureAwait(false);
                    var diagnosticsAtCaret = result.OfType <DiagnosticResult> ().Where(d => d.Region.Contains(loc)).Select(d => d.Diagnostic).ToList();

                    var codeIssueFixes = new List <ValidCodeDiagnosticAction> ();
                    var diagnosticIds = diagnosticsAtCaret.Select(diagnostic => diagnostic.Id).Concat(errorList.Select(rm => rm.Error.Id)).ToList();
                    if (codeFixes == null)
                    {
                        codeFixes = (await CodeRefactoringService.GetCodeFixesAsync(DocumentContext, CodeRefactoringService.MimeTypeToLanguage(Editor.MimeType), cancellationToken).ConfigureAwait(false)).ToList();
                    }
                    var root = await ad.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
                    foreach (var cfp in codeFixes)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return CodeActionContainer.Empty;
                        }
                        var provider = cfp.GetCodeFixProvider();
                        if (!provider.FixableDiagnosticIds.Any(diagnosticIds.Contains))
                        {
                            continue;
                        }

                        // These two delegates were factored out, as using them as lambdas in the inner loop creates more captures than declaring them here.
                        Func <Diagnostic, bool> providerIdsContain = d => provider.FixableDiagnosticIds.Contains(d.Id);
                        Action <Microsoft.CodeAnalysis.CodeActions.CodeAction, ImmutableArray <Diagnostic> > codeFixRegistration = (ca, d) => codeIssueFixes.Add(new ValidCodeDiagnosticAction(cfp, ca, d, d [0].Location.SourceSpan));
                        try {
                            var groupedDiagnostics = diagnosticsAtCaret
                                                     .Concat(errorList.Select(em => em.Error.Tag)
                                                             .OfType <Diagnostic> ())
                                                     .GroupBy(d => d.Location.SourceSpan);
                            foreach (var g in groupedDiagnostics)
                            {
                                if (cancellationToken.IsCancellationRequested)
                                {
                                    return CodeActionContainer.Empty;
                                }
                                var diagnosticSpan = g.Key;
                                var validDiagnostics = g.Where(providerIdsContain).ToImmutableArray();
                                if (validDiagnostics.Length == 0)
                                {
                                    continue;
                                }
                                if (diagnosticSpan.Start < 0 || diagnosticSpan.End > root.Span.End)
                                {
                                    continue;
                                }
                                await provider.RegisterCodeFixesAsync(new CodeFixContext(ad, diagnosticSpan, validDiagnostics, codeFixRegistration, cancellationToken)).ConfigureAwait(false);

                                // TODO: Is that right ? Currently it doesn't really make sense to run one code fix provider on several overlapping diagnostics at the same location
                                //       However the generate constructor one has that case and if I run it twice the same code action is generated twice. So there is a dupe check problem there.
                                // Work around for now is to only take the first diagnostic batch.
                                break;
                            }
                        } catch (OperationCanceledException) {
                            return CodeActionContainer.Empty;
                        } catch (AggregateException ae) {
                            ae.Flatten().Handle(aex => aex is OperationCanceledException);
                            return CodeActionContainer.Empty;
                        } catch (Exception ex) {
                            LoggingService.LogError("Error while getting refactorings from code fix provider " + cfp.Name, ex);
                            continue;
                        }
                    }
                    var codeActions = new List <ValidCodeAction> ();
                    foreach (var action in await CodeRefactoringService.GetValidActionsAsync(Editor, DocumentContext, span, cancellationToken).ConfigureAwait(false))
                    {
                        codeActions.Add(action);
                    }
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return CodeActionContainer.Empty;
                    }

                    var codeActionContainer = new CodeActionContainer(codeIssueFixes, codeActions, diagnosticsAtCaret);
                    Application.Invoke((o, args) => {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return;
                        }
                        if (codeActionContainer.IsEmpty)
                        {
                            RemoveWidget();
                            return;
                        }
                        CreateSmartTag(codeActionContainer, loc);
                    });
                    return codeActionContainer;
                } catch (AggregateException ae) {
                    ae.Flatten().Handle(aex => aex is OperationCanceledException);
                    return CodeActionContainer.Empty;
                } catch (OperationCanceledException) {
                    return CodeActionContainer.Empty;
                } catch (TargetInvocationException ex) {
                    if (ex.InnerException is OperationCanceledException)
                    {
                        return CodeActionContainer.Empty;
                    }
                    throw;
                }
            }, cancellationToken));
        }