public void AddMissingDependency_MissingMemberOfSupportedType_TypeIsNotMarkedMissing() { var targets = TargetPlatforms(2); var type = new MemberInfo { MemberDocId = "T:Spam.Spam", IsSupportedAcrossTargets = true, TargetStatus = targets.Select(t => new Version(t.Version.ToString())).ToList() }; var missingMember = MissingMember(type.MemberDocId, "Eggs"); missingMember.TargetStatus = new List <Version> { new Version("1.0"), null }; var reportingResult = new ReportingResult(targets, new List <MemberInfo>() { type }, Guid.NewGuid().ToString(), AnalyzeRequestFlags.None); reportingResult.AddMissingDependency(null, missingMember, "Add more spam."); var typeIsMarkedMissing = reportingResult.GetMissingTypes() .First(t => string.Equals(t.TypeName, type.MemberDocId, StringComparison.Ordinal)) .IsMissing; Assert.False(typeIsMarkedMissing); }
private void GenerateSummaryPage(Worksheet summaryPage, ReportingResult analysisResult) { var targetNames = _mapper.GetTargetNames(analysisResult.Targets, alwaysIncludeVersion: true); // This is the submission id summaryPage.AddRow(LocalizedStrings.SubmissionId, AddSubmissionLink(analysisResult.SubmissionId)); // This is the description of the app summaryPage.AddRow(LocalizedStrings.Description, _description); // This is the target list that was submitted to the service. summaryPage.AddRow(LocalizedStrings.Targets, string.Join(",", targetNames)); // Add an empty row. summaryPage.AddRow(); if (analysisResult.GetAssemblyUsageInfo().Any()) { var assemblyInfoHeader = new List <string> { LocalizedStrings.AssemblyHeader, "Target Framework" }; assemblyInfoHeader.AddRange(targetNames); int tableRowCount = 0; summaryPage.AddRow(assemblyInfoHeader.ToArray()); tableRowCount++; foreach (var item in analysisResult.GetAssemblyUsageInfo().OrderBy(a => a.SourceAssembly.AssemblyIdentity)) { var summaryData = new List <object>() { analysisResult.GetNameForAssemblyInfo(item.SourceAssembly), item.SourceAssembly.TargetFrameworkMoniker ?? string.Empty }; // TODO: figure out how to add formatting to cells to show percentages. summaryData.AddRange(item.UsageData.Select(pui => (object)Math.Round(pui.PortabilityIndex * 100.0, 2))); summaryPage.AddRow(summaryData.ToArray()); tableRowCount++; } summaryPage.AddConditionalFormatting(6, analysisResult.GetAssemblyUsageInfo().Count(), 3, analysisResult.Targets.Count); summaryPage.AddTable(5, tableRowCount, 1, assemblyInfoHeader.ToArray()); var columnWidths = new List <double> { ColumnWidths.SummaryPage.AssemblyName, ColumnWidths.SummaryPage.TFM }; columnWidths.AddRange(Enumerable.Repeat(ColumnWidths.Targets, analysisResult.Targets.Count)); // Targets summaryPage.AddColumnWidth(columnWidths); } summaryPage.AddRow(); summaryPage.AddRow(LocalizedStrings.CatalogLastUpdated, _catalogLastUpdated.ToString("D", CultureInfo.CurrentCulture)); summaryPage.AddRow(LocalizedStrings.HowToReadTheExcelTable); }
public void CreatesHtmlReport() { var mapper = Substitute.For <ITargetMapper>(); var writer = new HtmlReportWriter(mapper); var response = new AnalyzeResponse { MissingDependencies = new List <MemberInfo> { new MemberInfo { MemberDocId = "Type1.doc1", DefinedInAssemblyIdentity = "Assembly1", TypeDocId = "Type1" }, new MemberInfo { MemberDocId = "Type2.doc2", DefinedInAssemblyIdentity = "Assembly2", TypeDocId = "Type2" } }, SubmissionId = Guid.NewGuid().ToString(), Targets = new List <FrameworkName> { new FrameworkName("target1", Version.Parse("1.0.0.0")) }, UnresolvedUserAssemblies = new List <string> { "UnresolvedAssembly", "UnresolvedAssembly2", "UnresolvedAssembly3" }, BreakingChangeSkippedAssemblies = new List <AssemblyInfo>(), BreakingChanges = new List <BreakingChangeDependency>(), }; var reportingResult = new ReportingResult(response.Targets, response.MissingDependencies, response.SubmissionId, AnalyzeRequestFlags.NoTelemetry); response.ReportingResult = reportingResult; var tempFile = Path.GetTempFileName(); try { using (var file = File.OpenWrite(tempFile)) { writer.WriteStream(file, response); } Assert.True(File.Exists(tempFile)); var contents = File.ReadAllText(tempFile); Assert.True(!string.IsNullOrEmpty(contents)); Assert.Contains(response.SubmissionId, contents); } finally { if (File.Exists(tempFile)) { File.Delete(tempFile); } } }
private static string GenerateMissingTypes(string assembly, ReportingResult response, int i) { // for a given assembly identity and a given target usage, display the missing types IEnumerable <MissingTypeInfo> missingTypesForAssembly = response.GetMissingTypes() .Where(mt => mt.UsedIn.Any(x => x.AssemblyIdentity == assembly) && mt.IsMissing); var missingTypesForFramework = missingTypesForAssembly .Where(mt => mt.TargetStatus.ToList()[i] == "Not supported" || (mt.TargetVersionStatus.ToList()[i] > response.Targets[i].Version)) .Select(x => x.DocId).OrderBy(x => x); return(string.Join("\n", missingTypesForFramework)); }
public ExcelOpenXmlOutputWriter( ITargetMapper mapper, ReportingResult analysisReport, IEnumerable <BreakingChangeDependency> breakingChanges, DateTimeOffset catalogLastUpdated, string description = null) { _mapper = mapper; _analysisReport = analysisReport; _breakingChanges = breakingChanges; _description = description ?? string.Empty; _catalogLastUpdated = catalogLastUpdated; }
public CciMetadataTraverser(ReportingResult analysis, PdbReader pdbReader) { _analysis = analysis; _pdbReader = pdbReader; var missingMembers = from type in analysis.GetMissingTypes() from member in type.MissingMembers select member; _interestingMethods = missingMembers .ToDictionary(m => m.MemberName, m => m); _interestingTypes = analysis.GetMissingTypes() .Where(type => type.IsMissing) .ToDictionary(t => t.DocId, t => t); }
private void GenerateNuGetInfoPage(Worksheet page, ReportingResult analysisResult) { bool showAssemblyName = analysisResult.NuGetPackages.Any(p => !string.IsNullOrEmpty(p.AssemblyInfo)); var headerList = new List <string>() { LocalizedStrings.PackageIdHeader }; headerList.AddRange(_mapper.GetTargetNames(analysisResult.Targets)); if (showAssemblyName) { headerList.Add(LocalizedStrings.AssemblyHeader); } var header = headerList.ToArray(); page.AddRow(header); int rowCount = 1; foreach (var nugetInfo in analysisResult.NuGetPackages) { var rowContent = new List <string>() { nugetInfo.PackageId }; foreach (var target in analysisResult.Targets) { var supported = nugetInfo.SupportedVersions.TryGetValue(target, out var version) ? version : LocalizedStrings.NotSupported; rowContent.Add(supported); } if (showAssemblyName && nugetInfo.AssemblyInfo != null) { rowContent.Add(nugetInfo.AssemblyInfo); } page.AddRow(rowContent.ToArray()); rowCount++; } page.AddTable(1, rowCount, 1, header.ToArray()); page.AddColumnWidth(70, 40, 30, 30); }
public void AddMissingDependency_MemberOfUnidentifiedType_TypeAddedToMissingTypes() { var targets = TargetPlatforms(2); var typeDocId = "T:Spam.Spam"; var missingMember = MissingMember(typeDocId, "Eggs"); missingMember.TargetStatus = new List <Version> { new Version("1.0"), null }; var reportingResult = new ReportingResult(targets, new List <MemberInfo>(), Guid.NewGuid().ToString(), AnalyzeRequestFlags.None); reportingResult.AddMissingDependency(null, missingMember, "Add more spam."); var typeWasAdded = reportingResult.GetMissingTypes().Any(t => string.Equals(t.DocId, typeDocId, StringComparison.Ordinal)); Assert.True(typeWasAdded); }
public static void CreatesHtmlReport() { var mapper = Substitute.For <ITargetMapper>(); var writer = new HtmlReportWriter(mapper); var response = GetAnalyzeResponse(); // setting all show... flags renders every section of the report var flags = AnalyzeRequestFlags.NoTelemetry | AnalyzeRequestFlags.ShowBreakingChanges | AnalyzeRequestFlags.ShowNonPortableApis | AnalyzeRequestFlags.ShowRetargettingIssues; var reportingResult = new ReportingResult(response.Targets, response.MissingDependencies, response.SubmissionId, flags); response.ReportingResult = reportingResult; var tempFile = Path.GetTempFileName(); try { using (var file = File.OpenWrite(tempFile)) { writer.WriteStream(file, response); } Assert.True(File.Exists(tempFile)); var contents = File.ReadAllText(tempFile); Assert.True(!string.IsNullOrEmpty(contents)); Assert.Contains(response.SubmissionId, contents, StringComparison.Ordinal); } finally { if (File.Exists(tempFile)) { File.Delete(tempFile); } } }
public void AddMissingDependency_MemberOfUnidentifiedType_TypeInheritsMemberTargetStatus() { var targets = TargetPlatforms(2); var typeDocId = "T:Spam.Spam"; var missingMember = MissingMember(typeDocId, "Eggs"); missingMember.TargetStatus = new List <Version> { new Version("1.0"), null }; var reportingResult = new ReportingResult(targets, new List <MemberInfo>(), Guid.NewGuid().ToString(), AnalyzeRequestFlags.None); reportingResult.AddMissingDependency(null, missingMember, "Add more spam."); var type = reportingResult.GetMissingTypes() .First(t => string.Equals(t.TypeName, typeDocId, StringComparison.Ordinal)); Assert.True(missingMember.TargetStatus.Count == type.TargetVersionStatus.Count() && missingMember.TargetStatus.All(v => type.TargetVersionStatus.Contains(v))); }
public override IEnumerable <ISourceMappedItem> GetSourceInfo(string assemblyPath, string pdbPath, ReportingResult report) { using (var host = new HostEnvironment()) { using (var pdbFs = File.OpenRead(pdbPath)) { using (var pdbReader = new PdbReader(pdbFs, host)) { var metadataVisitor = new CciMetadataTraverser(assemblyPath, report, pdbReader); var traverser = new MetadataTraverser { PreorderVisitor = metadataVisitor, TraverseIntoMethodBodies = true }; var cciAssembly = host.LoadAssembly(assemblyPath); traverser.Traverse(cciAssembly); return(metadataVisitor.FoundItems); } } } }
private static void GenerateUnreferencedAssembliesPage(Worksheet missingAssembliesPage, ReportingResult analysisResult) { List <string> missingAssembliesPageHeader = new List <string>() { LocalizedStrings.AssemblyHeader, LocalizedStrings.UsedBy, LocalizedStrings.MissingAssemblyStatus }; int detailsRows = 0; missingAssembliesPage.AddRow(missingAssembliesPageHeader.ToArray()); detailsRows++; var unresolvedAssembliesMap = analysisResult.GetUnresolvedAssemblies(); foreach (var unresolvedAssemblyPair in unresolvedAssembliesMap.OrderBy(asm => asm.Key)) { if (unresolvedAssemblyPair.Value.Any()) { foreach (var usedIn in unresolvedAssemblyPair.Value) { missingAssembliesPage.AddRow(unresolvedAssemblyPair.Key, usedIn, LocalizedStrings.UnresolvedUsedAssembly); detailsRows++; } } else { missingAssembliesPage.AddRow(unresolvedAssemblyPair.Key, String.Empty, LocalizedStrings.UnresolvedUsedAssembly); } } // Generate the pretty table missingAssembliesPage.AddTable(1, detailsRows, 1, missingAssembliesPageHeader.ToArray()); missingAssembliesPage.AddColumnWidth(40, 40, 30); }
public Task WriteStreamAsync(Stream stream, AnalyzeResponse response) { // Create a new dgml every time write to a new stream. dgml = new DGMLManager(); ReferenceGraph rg = ReferenceGraph.CreateGraph(response); ReportingResult analysisResult = response.ReportingResult; var targets = analysisResult.Targets; GenerateTargetContainers(targets); dgml.SetTitle(response.ApplicationName); // For each target, let's generate the assemblies foreach (var node in rg.Nodes.Keys) { for (int i = 0; i < targets.Count; i++) { double portabilityIndex = 0, portabilityIndexRefs = 0; string missingTypes = null; if (node.UsageData != null) { TargetUsageInfo usageInfo = node.UsageData[i]; portabilityIndex = node.GetPortabilityIndex(i); portabilityIndexRefs = node.GetPortabilityIndexForReferences(i); missingTypes = GenerateMissingTypes(node.Assembly, analysisResult, i); } // generate the node string tfm = targets[i].FullName; Guid nodeGuid = dgml.GetOrCreateGuid($"{node.Assembly},TFM:{tfm}"); string nodeTitle = $"{node.SimpleName}: {Math.Round(portabilityIndex * 100, 2)}%, References: {Math.Round(portabilityIndexRefs * 100, 2)}%"; string nodeCategory = node.IsMissing ? "Unresolved" : GetCategory(Math.Round(portabilityIndex * portabilityIndexRefs * 100, 2)); dgml.AddNode(nodeGuid, nodeTitle, nodeCategory, portabilityIndex, group: string.IsNullOrEmpty(missingTypes) ? null : "Collapsed"); if (dgml.TryGetId(tfm, out Guid frameworkGuid)) { dgml.AddLink(frameworkGuid, nodeGuid, "Contains"); } if (!string.IsNullOrEmpty(missingTypes)) { Guid commentGuid = Guid.NewGuid(); dgml.AddNode(commentGuid, missingTypes, "Comment"); dgml.AddLink(nodeGuid, commentGuid, "Contains"); } } } // generate the references. foreach (var node in rg.Nodes.Keys) { for (int i = 0; i < targets.Count; i++) { // generate the node string tfm = targets[i].FullName; Guid nodeGuid = dgml.GetOrCreateGuid($"{node.Assembly},TFM:{tfm}"); foreach (var refNode in node.Nodes) { Guid refNodeGuid = dgml.GetOrCreateGuid($"{refNode.Assembly},TFM:{tfm}"); dgml.AddLink(nodeGuid, refNodeGuid); } } } dgml.Save(stream); return(Task.CompletedTask); }
public abstract IEnumerable <ISourceMappedItem> GetSourceInfo(string assemblyPath, string pdbPath, ReportingResult report);
/// <summary> /// Run tool with user input. /// </summary> private async void RunTool() { try { logger.Info("-->{0}", this.GetType().Name); // 1. Collect input parameters ReportingInputParams input = new ReportingInputParams { TractIDNames = Model.TractIDNames, SelectedTract = Model.SelectedTract, Authors = Model.Authors, Country = Model.Country, DepositType = Model.DepositType, DescModel = Model.DescModelPath, DescModelName = Model.DescModelName, GTModel = Model.GTModelPath, GTModelName = Model.GTModelName, AddDescriptive = Model.AddDescriptive.ToString(), AddGradeTon = Model.AddGradeTon.ToString(), EnableDescCheck = Model.EnableDescCheck.ToString(), EnableGTCheck = Model.EnableGTCheck.ToString(), TractImageFile = Model.TractImageFile, KnownDepositsFile = Model.KnownDepositsFile, ProspectsOccurencesFile = Model.ProspectsOccurencesFile, ExplorationFile = Model.ExplorationFile, SourcesFile = Model.SourcesFile, ReferencesFile = Model.ReferencesFile, AsDate = Model.AsDate, AsDepth = Model.AsDepth, AsLeader = Model.AsLeader, AsTeamMembers = Model.AsTeamMembers, IsUndiscDepDone = Model.IsUndiscDepDone, IsRaefDone = Model.IsRaefDone, IsScreenerDone = Model.IsScreenerDone }; // User can chöose not to insert Descriptive model document into report. if (Model.AddDescriptive == false) { input.DescModelName = "-"; } // User can chöose not to insert Grade Tonnage file into report. if (Model.AddGradeTon == false) { input.GTModelName = "-"; } // 2. Execute tool ReportingResult ddResult = default(ReportingResult); Model.IsBusy = true; await Task.Run(() => { ReportingTool tool = new ReportingTool(); logger.Info("calling ReportingTool.Execute(inputParams)"); ddResult = tool.Execute(input) as ReportingResult; logger.Trace("ReportingResult:\n" + "\tOutputFile: '{0}'", ddResult.OutputDocument); }); var lastRunFile = Path.Combine(settingsService.RootPath, "Reporting", "tract_report_last_run.lastrun"); File.Create(lastRunFile).Close(); dialogService.ShowNotification("Reporting tool completed successfully", "Success"); viewModelLocator.SettingsViewModel.WriteLogText("Reporting tool completed successfully.", "Success"); Model.LastRunDate = "Last Run: " + DateTime.Now.ToString("g"); Model.RunStatus = 1; } catch (Exception ex) { logger.Error(ex, "Failed to build documentation file"); dialogService.ShowNotification("Run failed. Check output for details\r\n- Are all input parameters correct?\r\n- Are all input files valid? \r\n- Are all input and output files closed?", "Error"); viewModelLocator.SettingsViewModel.WriteLogText("Reporting tool run failed. Check output for details\r\n- Are all input parameters correct?\r\n- Are all input files valid? \r\n- Are all input and output files closed?", "Error"); Model.RunStatus = 0; } finally { Model.IsBusy = false; } logger.Info("<--{0} completed", this.GetType().Name); }
private void GenerateDetailsPage(Worksheet detailsPage, ReportingResult analysisResult) { var showAssemblyColumn = analysisResult.GetAssemblyUsageInfo().Any(); var detailsPageHeader = new List <string>() { LocalizedStrings.TargetTypeHeader, LocalizedStrings.TargetMemberHeader }; if (showAssemblyColumn) { detailsPageHeader.Add(LocalizedStrings.AssemblyHeader); } detailsPageHeader.AddRange(_mapper.GetTargetNames(analysisResult.Targets, alwaysIncludeVersion: true)); detailsPageHeader.Add(LocalizedStrings.RecommendedChanges); int detailsRows = 0; detailsPage.AddRow(detailsPageHeader.ToArray()); detailsRows++; // Dump out all the types that were identified as missing from the target foreach (var item in analysisResult.GetMissingTypes().OrderByDescending(n => n.IsMissing)) { if (item.IsMissing) { if (!showAssemblyColumn) { // for a missing type we are going to dump the type name for both the target type and target member columns var rowContent = new List <object> { AddLink(item.TypeName), AddLink(item.TypeName) }; rowContent.AddRange(item.TargetStatus); rowContent.Add(item.RecommendedChanges); detailsPage.AddRow(rowContent.ToArray()); detailsRows++; } else { foreach (var assemblies in item.UsedIn) { string assemblyName = analysisResult.GetNameForAssemblyInfo(assemblies); // for a missing type we are going to dump the type name for both the target type and target member columns var rowContent = new List <object> { AddLink(item.TypeName), AddLink(item.TypeName), assemblyName }; rowContent.AddRange(item.TargetStatus); rowContent.Add(item.RecommendedChanges); detailsPage.AddRow(rowContent.ToArray()); detailsRows++; } } } foreach (var member in item.MissingMembers.OrderBy(type => type.MemberName)) { if (showAssemblyColumn) { foreach (var assem in member.UsedIn.OrderBy(asm => asm.AssemblyIdentity)) { string assemblyName = analysisResult.GetNameForAssemblyInfo(assem); var rowContent = new List <object> { AddLink(item.TypeName), AddLink(member.MemberName), assemblyName }; rowContent.AddRange(member.TargetStatus); rowContent.Add(member.RecommendedChanges); detailsPage.AddRow(rowContent.ToArray()); detailsRows++; } } else { var rowContent = new List <object> { AddLink(item.TypeName), AddLink(member.MemberName) }; rowContent.AddRange(member.TargetStatus); rowContent.Add(member.RecommendedChanges); detailsPage.AddRow(rowContent.ToArray()); detailsRows++; } } } // Generate the pretty tables detailsPage.AddTable(1, detailsRows, 1, detailsPageHeader.ToArray()); // Generate the columns var columnWidths = new List <double> { ColumnWidths.DetailsPage.TargetType, // Target type ColumnWidths.DetailsPage.TargetMember, // Target member ColumnWidths.DetailsPage.AssemblyName // Assembly name }; columnWidths.AddRange(Enumerable.Repeat(ColumnWidths.Targets, analysisResult.Targets.Count)); // Targets columnWidths.Add(ColumnWidths.DetailsPage.RecommendedChanges); // Recommended changes detailsPage.AddColumnWidth(columnWidths); }
public ReportingResult ComputeReport( IList <FrameworkName> targets, string submissionId, AnalyzeRequestFlags requestFlags, IDictionary <MemberInfo, ICollection <AssemblyInfo> > allDependencies, IList <MemberInfo> missingDependencies, IDictionary <string, ICollection <string> > unresolvedAssemblies, IList <string> unresolvedUserAssemblies, IEnumerable <string> assembliesWithErrors) { var types = allDependencies.Keys.Where(dep => dep.TypeDocId == null); ReportingResult result = new ReportingResult(targets, types, submissionId, requestFlags); missingDependencies #if !SILVERLIGHT .AsParallel() #endif .ForAll((Action <MemberInfo>)((item) => { // the calling assemblies are in Finder... if (allDependencies == null) { lock (result) { result.AddMissingDependency(null, item, item.RecommendedChanges); } } else { ICollection <AssemblyInfo> calledIn; if (!allDependencies.TryGetValue(item, out calledIn)) { return; } foreach (var callingAsm in calledIn) { lock (result) { result.AddMissingDependency(callingAsm, item, item.RecommendedChanges); } } } })); if (assembliesWithErrors != null) { foreach (var error in assembliesWithErrors) { result.AddAssemblyWithError(error); } } foreach (var unresolvedAssembly in unresolvedUserAssemblies) { result.AddUnresolvedUserAssembly(unresolvedAssembly, unresolvedAssemblies == null ? Enumerable.Empty <string>() : unresolvedAssemblies[unresolvedAssembly]); } // Compute per assembly report if (allDependencies != null) { var perAssemblyUsage = ComputePerAssemblyUsage(targets, missingDependencies, allDependencies); result.SetAssemblyUsageInfo(perAssemblyUsage); // Compute the map of assemblyInfo to name var assemblyNameMap = ComputeAssemblyNames(perAssemblyUsage); result.SetAssemblyNameMap(assemblyNameMap); } return(result); }
public CompatibilitySummaryModel(IDictionary <BreakingChange, IEnumerable <MemberInfo> > breaks, AssemblyInfo assembly, ReportingResult reportingResult) { Breaks = breaks; Assembly = assembly; ReportingResult = reportingResult; }
public IEnumerable <ISourceMappedItem> GetSourceInfo(IEnumerable <string> assemblyPaths, ReportingResult report) { var items = new List <ISourceMappedItem>(); _textOutput.WriteLine(); _textOutput.WriteLine(LocalizedStrings.FindingSourceLineInformationFor); int currentIssues = _progressReporter.Issues.Count; foreach (var assembly in assemblyPaths) { using (var task = _progressReporter.StartTask(string.Format(CultureInfo.InvariantCulture, "\t{0}\b\b\b", Path.GetFileName(assembly)))) { try { var pdbPath = _fileSystem.ChangeFileExtension(assembly, "pdb"); if (!_fileSystem.FileExists(pdbPath)) { _progressReporter.ReportIssue(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.PdbNotFoundFormat, assembly)); task.Abort(); } else { try { var sourceItems = GetSourceInfo(assembly, pdbPath, report); items.AddRange(sourceItems); } catch (OutOfMemoryException ex) { // TODO: Update Microsoft.CCI to support parsing portable pdbs. // Due to an OutOfMemoryException thrown when trying to parse portable pdb files. // https://github.com/icsharpcode/ILSpy/issues/789 // There is no public build for https://github.com/Microsoft/cci yet, which supports it. Trace.TraceError("OOM while trying to parse pdb file." + Environment.NewLine + ex.ToString()); _progressReporter.ReportIssue(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.SourceLineMappingNotSupportedPortablePdb, assembly)); task.Abort(); } } } catch (PortabilityAnalyzerException) { task.Abort(); } } var issues = _progressReporter.Issues.ToArray(); // There were more issues reported while running this current task. if (currentIssues < issues.Length) { for (int i = currentIssues; i < issues.Length; i++) { _textOutput.WriteLine(issues[i]); } currentIssues = issues.Length; } } return(items); }
public IEnumerable <ISourceMappedItem> GetSourceInfo(IEnumerable <string> assemblyPaths, ReportingResult report) { var items = new List <ISourceMappedItem>(); _textOutput.WriteLine(); _textOutput.WriteLine(LocalizedStrings.FindingSourceLineInformationFor); foreach (var assembly in assemblyPaths) { using (var task = _progressReporter.StartTask(string.Format("\t{0}\b\b\b", Path.GetFileName(assembly)))) { try { var pdbPath = _fileSystem.ChangeFileExtension(assembly, "pdb"); if (!_fileSystem.FileExists(pdbPath)) { _progressReporter.ReportIssue(string.Format(LocalizedStrings.PdbNotFoundFormat, assembly)); task.Abort(); continue; } items.AddRange(GetSourceInfo(assembly, pdbPath, report)); } catch (PortabilityAnalyzerException) { task.Abort(); } } } return(items); }