public static async Task<IEnumerable<Result>> Check (AnalysisDocument analysisDocument, CancellationToken cancellationToken)
		{
			var input = analysisDocument.DocumentContext;
			if (!AnalysisOptions.EnableFancyFeatures || input.Project == null || !input.IsCompileableInProject || input.AnalysisDocument == null)
				return Enumerable.Empty<Result> ();
			try {
				var model = input.ParsedDocument.GetAst<SemanticModel> ();
				if (model == null)
					return Enumerable.Empty<Result> ();
				var compilation = model.Compilation;
				var language = CodeRefactoringService.MimeTypeToLanguage (analysisDocument.Editor.MimeType);

				var providers = new List<DiagnosticAnalyzer> ();
				var alreadyAdded = new HashSet<Type>();
				if (diagnostics == null) {
					diagnostics = await CodeRefactoringService.GetCodeDiagnosticsAsync (analysisDocument.DocumentContext, language, cancellationToken);
				}
				foreach (var diagnostic in diagnostics) {
					if (alreadyAdded.Contains (diagnostic.DiagnosticAnalyzerType))
						continue;
					alreadyAdded.Add (diagnostic.DiagnosticAnalyzerType);
					var provider = diagnostic.GetProvider ();
					if (provider == null)
						continue;
					providers.Add (provider);
				}

				if (providers.Count == 0 || cancellationToken.IsCancellationRequested)
					return Enumerable.Empty<Result> ();
				#if DEBUG
				Debug.Listeners.Add (consoleTraceListener); 
				#endif

				CompilationWithAnalyzers compilationWithAnalyzer;
				var analyzers = System.Collections.Immutable.ImmutableArray<DiagnosticAnalyzer>.Empty.AddRange (providers);
				var diagnosticList = new List<Diagnostic> ();
				try {
					compilationWithAnalyzer = compilation.WithAnalyzers (analyzers, null, cancellationToken);
					if (input.ParsedDocument == null || cancellationToken.IsCancellationRequested)
						return Enumerable.Empty<Result> ();
					
					diagnosticList.AddRange (await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync (model, null, cancellationToken).ConfigureAwait (false));
					diagnosticList.AddRange (await compilationWithAnalyzer.GetAnalyzerSyntaxDiagnosticsAsync (model.SyntaxTree, cancellationToken).ConfigureAwait (false));
				} catch (Exception) {
					return Enumerable.Empty<Result> ();
				} finally {
					#if DEBUG
					Debug.Listeners.Remove (consoleTraceListener); 
					#endif
					CompilationWithAnalyzers.ClearAnalyzerState (analyzers);
				}

				return diagnosticList
					.Where (d => !d.Id.StartsWith("CS", StringComparison.Ordinal))
					.Select (diagnostic => {
						var res = new DiagnosticResult(diagnostic);
						// var line = analysisDocument.Editor.GetLineByOffset (res.Region.Start);
						// Console.WriteLine (diagnostic.Id + "/" + res.Region +"/" + analysisDocument.Editor.GetTextAt (line));
						return res;
					});
			} catch (OperationCanceledException) {
				return Enumerable.Empty<Result> ();
			}  catch (AggregateException ae) {
				ae.Flatten ().Handle (ix => ix is OperationCanceledException);
				return Enumerable.Empty<Result> ();
			} catch (Exception e) {
				LoggingService.LogError ("Error while running diagnostics.", e); 
				return Enumerable.Empty<Result> ();
			}
		}
Пример #2
0
        public static async Task <IEnumerable <Result> > Check(AnalysisDocument analysisDocument, CancellationToken cancellationToken)
        {
            var input = analysisDocument.DocumentContext;

            if (!AnalysisOptions.EnableFancyFeatures || input.Project == null || !input.IsCompileableInProject || input.AnalysisDocument == null)
            {
                return(Enumerable.Empty <Result> ());
            }
            try {
                var model = await analysisDocument.DocumentContext.AnalysisDocument.GetSemanticModelAsync(cancellationToken);

                if (model == null)
                {
                    return(Enumerable.Empty <Result> ());
                }
                var compilation = model.Compilation;
                var language    = CodeRefactoringService.MimeTypeToLanguage(analysisDocument.Editor.MimeType);

                var providers    = new List <DiagnosticAnalyzer> ();
                var alreadyAdded = new HashSet <Type>();
                if (diagnostics == null)
                {
                    diagnostics = await CodeRefactoringService.GetCodeDiagnosticsAsync(analysisDocument.DocumentContext, language, cancellationToken);
                }
                var diagnosticTable = new Dictionary <string, CodeDiagnosticDescriptor> ();
                foreach (var diagnostic in diagnostics)
                {
                    if (alreadyAdded.Contains(diagnostic.DiagnosticAnalyzerType))
                    {
                        continue;
                    }
                    if (!diagnostic.IsEnabled)
                    {
                        continue;
                    }
                    alreadyAdded.Add(diagnostic.DiagnosticAnalyzerType);
                    var provider = diagnostic.GetProvider();
                    if (provider == null)
                    {
                        continue;
                    }
                    foreach (var diag in provider.SupportedDiagnostics)
                    {
                        diagnosticTable [diag.Id] = diagnostic;
                    }
                    providers.Add(provider);
                }

                if (providers.Count == 0 || cancellationToken.IsCancellationRequested)
                {
                    return(Enumerable.Empty <Result> ());
                }
                                #if DEBUG
                Debug.Listeners.Add(consoleTraceListener);
                                #endif

                CompilationWithAnalyzers compilationWithAnalyzer;
                var analyzers = System.Collections.Immutable.ImmutableArray <DiagnosticAnalyzer> .Empty.AddRange(providers);

                var diagnosticList = new List <Diagnostic> ();
                try {
                    var options = new CompilationWithAnalyzersOptions(
                        null,
                        delegate(Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diag) {
                        LoggingService.LogError("Exception in diagnostic analyzer " + diag.Id + ":" + diag.GetMessage(), exception);
                    },
                        null,
                        false,
                        false
                        );

                    compilationWithAnalyzer = compilation.WithAnalyzers(analyzers, options);
                    if (input.ParsedDocument == null || cancellationToken.IsCancellationRequested)
                    {
                        return(Enumerable.Empty <Result> ());
                    }

                    diagnosticList.AddRange(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, cancellationToken).ConfigureAwait(false));
                    diagnosticList.AddRange(await compilationWithAnalyzer.GetAnalyzerSyntaxDiagnosticsAsync(model.SyntaxTree, cancellationToken).ConfigureAwait(false));
                } catch (Exception) {
                    return(Enumerable.Empty <Result> ());
                } finally {
                                        #if DEBUG
                    Debug.Listeners.Remove(consoleTraceListener);
                                        #endif
                    CompilationWithAnalyzers.ClearAnalyzerState(analyzers);
                }

                return(diagnosticList
                       .Where(d => !d.Id.StartsWith("CS", StringComparison.Ordinal))
                       .Where(d => diagnosticTable[d.Id].GetIsEnabled(d.Descriptor))
                       .Select(diagnostic => {
                    var res = new DiagnosticResult(diagnostic);
                    // var line = analysisDocument.Editor.GetLineByOffset (res.Region.Start);
                    // Console.WriteLine (diagnostic.Id + "/" + res.Region +"/" + analysisDocument.Editor.GetTextAt (line));
                    return res;
                }));
            } catch (OperationCanceledException) {
                return(Enumerable.Empty <Result> ());
            }  catch (AggregateException ae) {
                ae.Flatten().Handle(ix => ix is OperationCanceledException);
                return(Enumerable.Empty <Result> ());
            } catch (Exception e) {
                LoggingService.LogError("Error while running diagnostics.", e);
                return(Enumerable.Empty <Result> ());
            }
        }