public async Task AnalyzeProjectAsync(ICollection <Project> projects, CancellationToken cancellationToken = default(CancellationToken)) { var buildSucceeded = await _builder.BuildAsync(projects).ConfigureAwait(false); if (!buildSucceeded) { throw new PortabilityAnalyzerException(LocalizedStrings.UnableToBuildProject); } // TODO: Add option to include everything in output, not just build artifacts var targetAssemblies = new ConcurrentBag <string>(); var referencedNuGetPackages = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var project in projects) { var output = await _builder.GetBuildOutputFilesAsync(project).ConfigureAwait(false); // Could not find any output files for this. Skip it. if (output == null) { continue; } foreach (var file in output) { targetAssemblies.Add(file); } referencedNuGetPackages.UnionWith(GetPackageReferences(project)); } if (!targetAssemblies.Any()) { throw new PortabilityAnalyzerException(LocalizedStrings.FailedToLocateBuildOutputDir); } var result = await _analyzer.WriteAnalysisReportsAsync(targetAssemblies, referencedNuGetPackages, _reportWriter, true).ConfigureAwait(false); var sourceItems = await Task.Run(() => _sourceLineMapper.GetSourceInfo(targetAssemblies, result)).ConfigureAwait(false); var dictionary = new ConcurrentBag <CalculatedProject>(); foreach (var project in projects) { var outputFiles = await _builder.GetBuildOutputFilesAsync(project).ConfigureAwait(false); var hierarchy = await _projectMapper.GetVsHierarchyAsync(project).ConfigureAwait(false); dictionary.Add(new CalculatedProject(project, hierarchy, outputFiles ?? Enumerable.Empty <string>())); } await _errorList.DisplaySourceItemsAsync(sourceItems, dictionary.ToArray()).ConfigureAwait(false); }