From b49f3d4ade54b22d9493aa2b1541ee45ba38b705 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Tue, 19 Jun 2018 17:00:24 -0700 Subject: [PATCH 01/17] Add check IsExplicitySpecified transform (#682) --- .../Microsoft.Fx.Portability/ApiPortClient.cs | 2 +- .../ApiPortClientTests.cs | 134 ++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs b/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs index 23f9bc768..d6772486c 100644 --- a/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs +++ b/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs @@ -270,7 +270,7 @@ private AnalyzeRequest GenerateRequest(IApiPortOptions options, IDependencyInfo foreach (var assembly in dependencyInfo.UserAssemblies) { // Windows's file paths are case-insensitive - var matchingAssembly = options.InputAssemblies.SingleOrDefault(x => x.Key.Name.Equals(assembly.Location, StringComparison.OrdinalIgnoreCase)); + var matchingAssembly = options.InputAssemblies.FirstOrDefault(x => x.Key.Name.Equals(assembly.Location, StringComparison.OrdinalIgnoreCase)); // AssemblyInfo is explicitly specified if we found a matching // assembly location in the input dictionary AND the value is diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortClientTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortClientTests.cs index f6f5de5d3..37d9a0d64 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortClientTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortClientTests.cs @@ -5,7 +5,9 @@ using Microsoft.Fx.Portability.ObjectModel; using Microsoft.Fx.Portability.Reporting; using NSubstitute; +using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.Linq; using System.Threading.Tasks; @@ -62,5 +64,137 @@ public static async Task WriteAnalysisReports_ThrowsOnInvalidOptions_TargetCount await Assert.ThrowsAsync(() => client.WriteAnalysisReportsAsync(options)); await Assert.ThrowsAsync(() => client.WriteAnalysisReportsAsync(options, true)); } + + [Fact] + public static async Task SingleAssemblyFile() + { + var files = new[] + { + new AssemblyInfo + { + AssemblyIdentity = "file1", + FileVersion = "1.0.0", + Location = "file1", + IsExplicitlySpecified = false + } + }; + + await UserAssemblyTestsAsync(files); + } + + [Fact] + public static async Task TwoAssemblyFiles() + { + var files = new[] + { + new AssemblyInfo + { + AssemblyIdentity = "file1", + FileVersion = "1.0.0", + Location = "file1", + IsExplicitlySpecified = false + }, + new AssemblyInfo + { + AssemblyIdentity = "file2", + FileVersion = "1.0.0", + Location = "file2", + IsExplicitlySpecified = true + } + }; + + await UserAssemblyTestsAsync(files); + } + + [Fact] + public static async Task DuplicateAssemblyFile() + { + var files = new[] + { + new AssemblyInfo + { + AssemblyIdentity = "file1", + FileVersion = "1.0.0", + Location = "file1", + IsExplicitlySpecified = false + }, + new AssemblyInfo + { + AssemblyIdentity = "file1", + FileVersion = "1.0.0", + Location = "file1", + IsExplicitlySpecified = true + } + }; + + await UserAssemblyTestsAsync(files); + } + + [Fact] + public static async Task DuplicateNameDifferentVersion() + { + var files = new[] + { + new AssemblyInfo + { + AssemblyIdentity = "file1", + FileVersion = "1.0.0", + Location = "file1", + IsExplicitlySpecified = true + }, + new AssemblyInfo + { + AssemblyIdentity = "file3", + FileVersion = "1.0.1", + Location = "file3", + IsExplicitlySpecified = false + } + }; + + await UserAssemblyTestsAsync(files); + } + + private static async Task UserAssemblyTestsAsync(IEnumerable assemblies) + { + var service = Substitute.For(); + var progressReporter = Substitute.For(); + var targetMapper = Substitute.For(); + var dependencyFinder = Substitute.For(); + var reportGenerator = Substitute.For(); + var ignoreAssemblyInfoList = Substitute.For>(); + var writer = Substitute.For(); + + service.SendAnalysisAsync(Arg.Any(), Arg.Any>()).Returns( + ServiceResponse.Create(Enumerable.Empty())); + + var client = new ApiPortClient(service, progressReporter, targetMapper, dependencyFinder, reportGenerator, ignoreAssemblyInfoList, writer); + var options = Substitute.For(); + + IAssemblyFile CreateAssemblyFile(AssemblyInfo assemblyInfo) + { + var file = Substitute.For(); + file.Name.Returns(assemblyInfo.AssemblyIdentity); + file.Version.Returns(assemblyInfo.FileVersion); + file.Exists.Returns(true); + return file; + } + + var assemblyFiles = assemblies.Where(a => a.IsExplicitlySpecified).ToImmutableDictionary(CreateAssemblyFile, _ => false); + options.InputAssemblies.Returns(assemblyFiles); + + var info = Substitute.For(); + info.UserAssemblies.Returns(assemblies); + + dependencyFinder.FindDependencies(Arg.Any>(), progressReporter) + .Returns(info); + + await client.WriteAnalysisReportsAsync(options); + + Assert.All(assemblies, a => + { + var expected = assemblies.First(t => string.Equals(t.Location, a.Location, StringComparison.OrdinalIgnoreCase)).IsExplicitlySpecified; + Assert.Equal(expected, a.IsExplicitlySpecified); + }); + } } } From 5c327f26afadfd2cda11faff25fafc66408b7123 Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Sat, 8 Sep 2018 19:22:18 -0700 Subject: [PATCH 02/17] Removing Ubuntu14.04 for builds because there are no hosts (#705) --- netci.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netci.groovy b/netci.groovy index ca1db7b63..ad47c14bc 100644 --- a/netci.groovy +++ b/netci.groovy @@ -4,7 +4,7 @@ import jobs.generation.Utilities; def project = GithubProject def branch = GithubBranchName def configurationGroups = ['Debug', 'Release'] -def outerloopPlatforms = ['Windows_NT', 'Ubuntu14.04', 'Ubuntu16.04', 'OSX10.12'] +def outerloopPlatforms = ['Windows_NT', 'Ubuntu16.04', 'OSX10.12'] // Generate the builds for debug and release, commit and PRJob [true, false].each { isPR -> // Defines a closure over true and false, value assigned to isPR From c03c2c1e44223ceca30f53ec0f1e7e660ef29923 Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Mon, 10 Sep 2018 14:53:08 -0700 Subject: [PATCH 03/17] Using HTTPS link instead of HTTP (#703) --- src/lib/Microsoft.Fx.Portability/DocumentationLinks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Microsoft.Fx.Portability/DocumentationLinks.cs b/src/lib/Microsoft.Fx.Portability/DocumentationLinks.cs index 3d920b959..ce42e611a 100644 --- a/src/lib/Microsoft.Fx.Portability/DocumentationLinks.cs +++ b/src/lib/Microsoft.Fx.Portability/DocumentationLinks.cs @@ -9,6 +9,6 @@ public static class DocumentationLinks { public static readonly Uri PrivacyPolicy = new Uri("https://privacy.microsoft.com/en-us/privacystatement"); - public static readonly Uri About = new Uri("http://go.microsoft.com/fwlink/?LinkId=506955"); + public static readonly Uri About = new Uri("https://go.microsoft.com/fwlink/?LinkId=506955"); } } From 61e6aeec52cfbef08cb932745b2aa797f5cfcb62 Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Mon, 10 Sep 2018 14:53:23 -0700 Subject: [PATCH 04/17] Adding back in some style-cop rules. Part 1 (#704) * Fixing SA1649: File names must match class * Adding back the suppression of most StyleCop rules except for SA1516 and SA1649 * Fixing SA1516: Elements should be separated by a blank line * Fixing some more SA1516 warnings --- rules.ruleset | 2 - .../ProjectBuilder2017.cs | 1 + .../ComProjectMapper.cs | 4 +- .../DefaultProjectBuilder.cs | 10 +- .../Models/SelectedResultFormat.cs | 12 +- .../Models/TargetPlatformVersion.cs | 13 +- .../NotifyPropertyBase.cs | 1 + .../ViewModels/OptionsViewModel.cs | 34 ++- .../ApiPort.VisualStudio/ApiPortVSPackage.cs | 16 +- src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs | 8 +- .../ApiPort.VisualStudio/ServiceProvider.cs | 6 +- src/ApiPort/ApiPort/DocIdSearchRepl.cs | 5 +- .../Proxy/ConsoleCredentialProvider.cs | 1 + src/ApiPort/ApiPort/Proxy/WebProxy.cs | 1 + .../Analyzer/MemberDependency.cs | 27 +- .../HostEnvironment.cs | 202 ++++++++----- .../TypeExtensions.cs | 265 ++++++++++++------ .../MemberDependency.cs | 35 ++- .../MemberModifiedMetadata.cs | 1 + .../OfflineApiPortService.cs | 2 +- .../ExcelOpenXmlOutputWriter.cs | 3 +- .../HyperlinkCell.cs | 2 + ...heetExtensions.cs => OpenXmlExtensions.cs} | 0 .../CompatibilityResultsModel.cs | 4 + .../CompatibilitySummaryModel.cs | 2 + .../HtmlReportWriter.cs | 1 + .../Analyzer/IDependencyInfo.cs | 3 + .../Microsoft.Fx.Portability/ApiDefinition.cs | 2 + .../BreakingChangeDependency.cs | 6 +- .../IApiPortOptions.cs | 10 + .../IApiPortService.cs | 7 + .../IProgressReporter.cs | 4 + .../Microsoft.Fx.Portability/IProgressTask.cs | 1 + .../Microsoft.Fx.Portability/ITargetMapper.cs | 3 + .../ObjectModel/ApiInfoStorage.cs | 5 + .../ObjectModel/ApiMetadataStorage.cs | 1 + .../ObjectModel/AssemblyInfo.cs | 10 +- .../ObjectModel/AvailableTarget.cs | 4 + .../ObjectModel/CompatibilityRange.cs | 5 + .../ObjectModel/DiagnosticAnalyzerInfo.cs | 11 +- .../ObjectModel/DotNetCatalog.cs | 4 + .../ObjectModel/IApiCatalogLookup.cs | 14 + .../ObjectModel/IStorage.cs | 4 + .../ObjectModel/IgnoreAssemblyInfo.cs | 22 +- .../ObjectModel/MemberInfo.cs | 27 +- .../ObjectModel/TargetInformation.cs | 36 +-- .../PortabilityAnalyzerException.cs | 11 +- .../Reporting/IFileSystem.cs | 7 + .../Reporting/IReportWriter.cs | 1 + .../Reporting/ObjectModel/MissingInfo.cs | 4 +- .../ObjectModel/MissingMemberInfo.cs | 19 +- .../Reporting/ObjectModel/ReportingResult.cs | 37 +-- ...latformUsageInfo.cs => TargetUsageInfo.cs} | 0 .../ResultFormatInformation.cs | 2 + .../ServiceResponse.cs | 1 + .../StringContainsSearcher.cs | 4 +- .../JsonMultiDictionaryConverter.cs | 1 + stylecop.json | 2 + ...=> AnalysisEngineNuGetPackageInfoTests.cs} | 9 +- .../Analysis/AnalysisEngineTests.cs | 1 + .../ApiPortServiceTests.cs | 1 + .../NuGetPackageInfoComparerTests.cs | 1 + .../TargetMapTests.cs | 2 +- .../TestData/TestDotNetCatalog.cs | 15 +- 64 files changed, 667 insertions(+), 288 deletions(-) rename src/lib/Microsoft.Fx.Portability.Reports.Excel/{ExcelSpreadsheetExtensions.cs => OpenXmlExtensions.cs} (100%) rename src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/{PlatformUsageInfo.cs => TargetUsageInfo.cs} (100%) rename tests/lib/Microsoft.Fx.Portability.Tests/Analysis/{AnalysisEngine.NuGetPackageInfo.Tests.cs => AnalysisEngineNuGetPackageInfoTests.cs} (98%) diff --git a/rules.ruleset b/rules.ruleset index f679c7ced..e0d798f99 100644 --- a/rules.ruleset +++ b/rules.ruleset @@ -177,7 +177,6 @@ - @@ -224,7 +223,6 @@ - diff --git a/src/ApiPort/ApiPort.VisualStudio.2017/ProjectBuilder2017.cs b/src/ApiPort/ApiPort.VisualStudio.2017/ProjectBuilder2017.cs index 1d41859b2..47dd43346 100644 --- a/src/ApiPort/ApiPort.VisualStudio.2017/ProjectBuilder2017.cs +++ b/src/ApiPort/ApiPort.VisualStudio.2017/ProjectBuilder2017.cs @@ -15,6 +15,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; + using static Microsoft.Fx.Portability.Utils.FormattableStringHelper; namespace ApiPortVS.VS2017 diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/ComProjectMapper.cs b/src/ApiPort/ApiPort.VisualStudio.Common/ComProjectMapper.cs index 411575cde..fdfa69c10 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/ComProjectMapper.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/ComProjectMapper.cs @@ -8,9 +8,11 @@ using System; using System.Diagnostics; using System.Threading.Tasks; -using VisualStudio = Microsoft.VisualStudio.Shell; + using static Microsoft.Fx.Portability.Utils.FormattableStringHelper; +using VisualStudio = Microsoft.VisualStudio.Shell; + namespace ApiPortVS { /// diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/DefaultProjectBuilder.cs b/src/ApiPort/ApiPort.VisualStudio.Common/DefaultProjectBuilder.cs index eef4be0c8..de4ac594e 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/DefaultProjectBuilder.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/DefaultProjectBuilder.cs @@ -3,18 +3,18 @@ using ApiPortVS.Contracts; using EnvDTE; +using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell.Interop; +using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; +using System.Threading; using System.Threading.Tasks; -using static Microsoft.VisualStudio.VSConstants; using static Microsoft.Fx.Portability.Utils.FormattableStringHelper; -using System; -using System.Threading; -using Microsoft.VisualStudio; -using System.Diagnostics; +using static Microsoft.VisualStudio.VSConstants; namespace ApiPortVS { diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/Models/SelectedResultFormat.cs b/src/ApiPort/ApiPort.VisualStudio.Common/Models/SelectedResultFormat.cs index 12c31439b..ef7a5ee15 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/Models/SelectedResultFormat.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/Models/SelectedResultFormat.cs @@ -12,9 +12,14 @@ namespace ApiPortVS public class SelectedResultFormat : ResultFormatInformation, INotifyPropertyChanged { private bool _isSelected; + public bool IsSelected { - get { return _isSelected; } + get + { + return _isSelected; + } + set { if (_isSelected == value) @@ -34,7 +39,10 @@ private void RaisePropertyChanged([CallerMemberName]string property = "") PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } - public SelectedResultFormat() { } + public SelectedResultFormat() + { + } + public SelectedResultFormat(ResultFormatInformation format, bool isSelected) { DisplayName = format.DisplayName; diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatformVersion.cs b/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatformVersion.cs index 81282bf79..5319be483 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatformVersion.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatformVersion.cs @@ -9,6 +9,7 @@ namespace ApiPortVS public class TargetPlatformVersion : NotifyPropertyBase { private string _platformName; + public string PlatformName { get { return _platformName; } @@ -16,6 +17,7 @@ public string PlatformName } private bool _isSelected; + public bool IsSelected { get { return _isSelected; } @@ -23,6 +25,7 @@ public bool IsSelected } private Version _version; + public Version Version { get { return _version; } @@ -43,14 +46,12 @@ public override string ToString() public override bool Equals(object obj) { - var other = obj as TargetPlatformVersion; - - if (other == null) + if (!(obj is TargetPlatformVersion other)) { return false; } - return String.Equals(PlatformName, other.PlatformName, StringComparison.OrdinalIgnoreCase) + return string.Equals(PlatformName, other.PlatformName, StringComparison.OrdinalIgnoreCase) && Version == other.Version; } @@ -62,8 +63,8 @@ public override int GetHashCode() { int hash = 17; - hash = hash * HashMultipler + PlatformName.GetHashCode(); - hash = hash * HashMultipler + Version.GetHashCode(); + hash = (hash * HashMultipler) + PlatformName.GetHashCode(); + hash = (hash * HashMultipler) + Version.GetHashCode(); return hash; } diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/NotifyPropertyBase.cs b/src/ApiPort/ApiPort.VisualStudio.Common/NotifyPropertyBase.cs index b98fe1193..127d7357c 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/NotifyPropertyBase.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/NotifyPropertyBase.cs @@ -12,6 +12,7 @@ namespace ApiPortVS public class NotifyPropertyBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; + protected SynchronizationContext Context { get; } public NotifyPropertyBase() diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/ViewModels/OptionsViewModel.cs b/src/ApiPort/ApiPort.VisualStudio.Common/ViewModels/OptionsViewModel.cs index 01469e042..b59e060eb 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/ViewModels/OptionsViewModel.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/ViewModels/OptionsViewModel.cs @@ -29,6 +29,7 @@ public sealed class OptionsViewModel : NotifyPropertyBase, IDisposable private bool _hasError; private bool _updating; private bool _saveMetadata; + private string _errorMessage; public OptionsViewModel(IApiPortService apiPort, ITargetMapper targetMapper, OptionsModel optionsModel) { @@ -51,7 +52,11 @@ public OptionsViewModel(IApiPortService apiPort, ITargetMapper targetMapper, Opt public IList Formats { - get { return _optionsModel.Formats; } + get + { + return _optionsModel.Formats; + } + set { _optionsModel.Formats = value; @@ -61,7 +66,11 @@ public IList Formats public IList Targets { - get { return _optionsModel.Platforms; } + get + { + return _optionsModel.Platforms; + } + set { _optionsModel.Platforms = value; @@ -84,7 +93,11 @@ public bool UpdatingPlatforms public string OutputDirectory { - get { return _optionsModel.OutputDirectory; } + get + { + return _optionsModel.OutputDirectory; + } + set { _optionsModel.OutputDirectory = value; @@ -94,7 +107,11 @@ public string OutputDirectory public string DefaultOutputName { - get { return _optionsModel.DefaultOutputName; } + get + { + return _optionsModel.DefaultOutputName; + } + set { _optionsModel.DefaultOutputName = value; @@ -108,7 +125,6 @@ public bool HasError set { UpdateProperty(ref _hasError, value); } } - private string _errorMessage; public string ErrorMessage { get { return _errorMessage; } @@ -204,15 +220,14 @@ private async Task UpdateTargetsAsync() return new TargetPlatform { Name = t.Key, - Versions = t.Select(v => new TargetPlatformVersion { PlatformName = t.Key, Version = v.Version, - IsSelected = v.IsSet + IsSelected = v.IsSet, }) .OrderBy(v => v.Version) - .ToList() + .ToList(), }; }); @@ -244,7 +259,7 @@ private void UpdateTargetPlatforms(IEnumerable targetPlatforms) { foreach (var name in _targetMapper.GetNames(alias)) { - if (String.Equals(platform.Name, name, StringComparison.Ordinal)) + if (string.Equals(platform.Name, name, StringComparison.Ordinal)) { platform.AlternativeNames.Add(alias); } @@ -289,6 +304,7 @@ private void TargetPlatformAndResultFormatPropertyChanged(object sender, Propert HasError = false; ErrorMessage = string.Empty; } + break; } } diff --git a/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs b/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs index 457f7221e..69aecee47 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs +++ b/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs @@ -59,41 +59,41 @@ protected override void Initialize() var menuInitializer = LocalServiceProvider.GetService(typeof(AnalyzeMenu)) as AnalyzeMenu; // Add menu items for Analyze toolbar menu - CommandID anazlyMenuCommandID = new CommandID(Guids.AnalyzeMenuItemCmdSet, (int)PkgCmdIDList.CmdIdAnalyzeMenuItem); + CommandID anazlyMenuCommandID = new CommandID(Guids.AnalyzeMenuItemCmdSet, (int)PkgCmdID.CmdIdAnalyzeMenuItem); MenuCommand menuItem = new MenuCommand(menuInitializer.AnalyzeMenuItemCallback, anazlyMenuCommandID); mcs.AddCommand(menuItem); - CommandID analyzeMenuOptionsCommandID = new CommandID(Guids.AnalyzeMenuItemCmdSet, (int)PkgCmdIDList.CmdIdAnalyzeOptionsMenuItem); + CommandID analyzeMenuOptionsCommandID = new CommandID(Guids.AnalyzeMenuItemCmdSet, (int)PkgCmdID.CmdIdAnalyzeOptionsMenuItem); MenuCommand analyzeMenuOptionsItem = new MenuCommand(ShowOptionsPage, analyzeMenuOptionsCommandID); mcs.AddCommand(analyzeMenuOptionsItem); - CommandID analyzeMenuToolbarCommandID = new CommandID(Guids.AnalyzeMenuItemCmdSet, (int)PkgCmdIDList.CmdIdAnalyzeToolbarMenuItem); + CommandID analyzeMenuToolbarCommandID = new CommandID(Guids.AnalyzeMenuItemCmdSet, (int)PkgCmdID.CmdIdAnalyzeToolbarMenuItem); MenuCommand analyzeMenuToolbarItem = new MenuCommand(async (_, __) => await ShowToolbarAsync().ConfigureAwait(false), analyzeMenuToolbarCommandID); mcs.AddCommand(analyzeMenuToolbarItem); // Add menu items for Project context menus - CommandID projectContextMenuCmdId = new CommandID(Guids.ProjectContextMenuItemCmdSet, (int)PkgCmdIDList.CmdIdProjectContextMenuItem); + CommandID projectContextMenuCmdId = new CommandID(Guids.ProjectContextMenuItemCmdSet, (int)PkgCmdID.CmdIdProjectContextMenuItem); OleMenuCommand contextMenuItem = new OleMenuCommand(async (_, __) => await menuInitializer.AnalyzeSelectedProjectsAsync(false), projectContextMenuCmdId); contextMenuItem.BeforeQueryStatus += menuInitializer.ProjectContextMenuItemBeforeQueryStatus; mcs.AddCommand(contextMenuItem); - CommandID projectContextMenuDependentsCmdId = new CommandID(Guids.ProjectContextMenuItemCmdSet, (int)PkgCmdIDList.CmdIdProjectContextDependentsMenuItem); + CommandID projectContextMenuDependentsCmdId = new CommandID(Guids.ProjectContextMenuItemCmdSet, (int)PkgCmdID.CmdIdProjectContextDependentsMenuItem); OleMenuCommand contextMenuDependentsItem = new OleMenuCommand(async (_, __) => await menuInitializer.AnalyzeSelectedProjectsAsync(true), projectContextMenuDependentsCmdId); contextMenuDependentsItem.BeforeQueryStatus += menuInitializer.ProjectContextMenuDependenciesItemBeforeQueryStatus; mcs.AddCommand(contextMenuDependentsItem); - CommandID projectContextMenuOptionsCmdId = new CommandID(Guids.ProjectContextMenuItemCmdSet, (int)PkgCmdIDList.CmdIdProjectContextOptionsMenuItem); + CommandID projectContextMenuOptionsCmdId = new CommandID(Guids.ProjectContextMenuItemCmdSet, (int)PkgCmdID.CmdIdProjectContextOptionsMenuItem); OleMenuCommand contextMenuOptionsItem = new OleMenuCommand(ShowOptionsPage, projectContextMenuOptionsCmdId); contextMenuOptionsItem.BeforeQueryStatus += menuInitializer.ProjectContextMenuItemBeforeQueryStatus; mcs.AddCommand(contextMenuOptionsItem); // Add menu items for Solution context menus - CommandID solutionContextMenuCmdId = new CommandID(Guids.SolutionContextMenuItemCmdSet, (int)PkgCmdIDList.CmdIdSolutionContextMenuItem); + CommandID solutionContextMenuCmdId = new CommandID(Guids.SolutionContextMenuItemCmdSet, (int)PkgCmdID.CmdIdSolutionContextMenuItem); OleMenuCommand solutionContextMenuItem = new OleMenuCommand(menuInitializer.SolutionContextMenuItemCallback, solutionContextMenuCmdId); solutionContextMenuItem.BeforeQueryStatus += menuInitializer.SolutionContextMenuItemBeforeQueryStatus; mcs.AddCommand(solutionContextMenuItem); - CommandID solutionContextMenuOptionsCmdId = new CommandID(Guids.SolutionContextMenuItemCmdSet, (int)PkgCmdIDList.CmdIdSolutionContextOptionsMenuItem); + CommandID solutionContextMenuOptionsCmdId = new CommandID(Guids.SolutionContextMenuItemCmdSet, (int)PkgCmdID.CmdIdSolutionContextOptionsMenuItem); OleMenuCommand solutionContextMenuOptionsItem = new OleMenuCommand(ShowOptionsPage, solutionContextMenuOptionsCmdId); solutionContextMenuOptionsItem.BeforeQueryStatus += menuInitializer.SolutionContextMenuItemBeforeQueryStatus; mcs.AddCommand(solutionContextMenuOptionsItem); diff --git a/src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs b/src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs index 3a5d99d6d..33c526b81 100644 --- a/src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs +++ b/src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs @@ -1,11 +1,13 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -// MUST match PkgCmdID.h - namespace ApiPortVS { - internal static class PkgCmdIDList + /// + /// Command ids for Visual Studio menu items + /// MUST match PkgCmdID.h + /// + internal static class PkgCmdID { public const uint CmdIdAnalyzeMenuItem = 0x0100; public const uint CmdIdAnalyzeOptionsMenuItem = 0x0101; diff --git a/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs b/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs index fa985dfdb..a9f5074c7 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs +++ b/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs @@ -4,8 +4,8 @@ using ApiPortVS.Analyze; using ApiPortVS.Contracts; using ApiPortVS.Models; -using ApiPortVS.Resources; using ApiPortVS.Reporting; +using ApiPortVS.Resources; using ApiPortVS.SourceMapping; using ApiPortVS.ViewModels; using ApiPortVS.Views; @@ -18,11 +18,11 @@ using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using static Microsoft.VisualStudio.VSConstants; -using System.Linq; -using System.Collections.Generic; namespace ApiPortVS { diff --git a/src/ApiPort/ApiPort/DocIdSearchRepl.cs b/src/ApiPort/ApiPort/DocIdSearchRepl.cs index 03af7639d..15316459e 100644 --- a/src/ApiPort/ApiPort/DocIdSearchRepl.cs +++ b/src/ApiPort/ApiPort/DocIdSearchRepl.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.Linq; using System.Threading.Tasks; + using static Microsoft.Fx.Portability.Utils.FormattableStringHelper; namespace ApiPort @@ -14,6 +15,7 @@ namespace ApiPort public class DocIdSearchRepl { private readonly ISearcher _searcher; + public DocIdSearchRepl(ISearcher searcher) { _searcher = searcher; @@ -75,9 +77,8 @@ private async Task ReplLoopAsync() .Replace(LocalizedStrings.ReplOptionCount, string.Empty) #endif .Trim(); - int updatedCount; - if (Int32.TryParse(trimmed, out updatedCount)) + if (int.TryParse(trimmed, out var updatedCount)) { count = updatedCount; WriteColorLine(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.ReplUpdatedCount, count), ConsoleColor.Yellow); diff --git a/src/ApiPort/ApiPort/Proxy/ConsoleCredentialProvider.cs b/src/ApiPort/ApiPort/Proxy/ConsoleCredentialProvider.cs index 4295f49cd..76b904ab8 100644 --- a/src/ApiPort/ApiPort/Proxy/ConsoleCredentialProvider.cs +++ b/src/ApiPort/ApiPort/Proxy/ConsoleCredentialProvider.cs @@ -116,6 +116,7 @@ private static void ReadSecureStringFromConsole(SecureString secureString) Console.Write('*'); } } + Console.WriteLine(); } diff --git a/src/ApiPort/ApiPort/Proxy/WebProxy.cs b/src/ApiPort/ApiPort/Proxy/WebProxy.cs index 1d02923de..5e5acda0f 100644 --- a/src/ApiPort/ApiPort/Proxy/WebProxy.cs +++ b/src/ApiPort/ApiPort/Proxy/WebProxy.cs @@ -43,6 +43,7 @@ public IReadOnlyList BypassList { return _bypassList; } + set { _bypassList = value ?? new string[] { }; diff --git a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/MemberDependency.cs b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/MemberDependency.cs index 00cbc9e98..f557f257c 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/MemberDependency.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/MemberDependency.cs @@ -17,16 +17,20 @@ internal class MemberDependency private string _typeDocId; /// - /// This represents the assembly that is calling the member + /// Gets or sets the assembly that is calling the member /// public AssemblyInfo CallingAssembly { get; set; } /// - /// This represents the assembly in which the member is defined + /// Gets or sets the assembly in which the member is defined /// public string DefinedInAssemblyIdentity { - get { return _definedInAssemblyIdentity; } + get + { + return _definedInAssemblyIdentity; + } + set { _definedInAssemblyIdentity = value; @@ -36,7 +40,11 @@ public string DefinedInAssemblyIdentity public string MemberDocId { - get { return _memberDocId; } + get + { + return _memberDocId; + } + set { _memberDocId = value; @@ -46,7 +54,11 @@ public string MemberDocId public string TypeDocId { - get { return _typeDocId; } + get + { + return _typeDocId; + } + set { _typeDocId = value; @@ -61,9 +73,11 @@ public override string ToString() public override bool Equals(object obj) { - MemberDependency other = obj as MemberDependency; + var other = obj as MemberDependency; if (other == null) + { return false; + } return StringComparer.Ordinal.Equals(MemberDocId, other.MemberDocId) && StringComparer.Ordinal.Equals(DefinedInAssemblyIdentity, other.DefinedInAssemblyIdentity) && @@ -77,6 +91,7 @@ public override int GetHashCode() _hashCode = ((DefinedInAssemblyIdentity ?? string.Empty) + (MemberDocId ?? string.Empty)).GetHashCode() ^ CallingAssembly.GetHashCode(); _hashComputed = true; } + return _hashCode; } } diff --git a/src/lib/Microsoft.Fx.Portability.Cci/HostEnvironment.cs b/src/lib/Microsoft.Fx.Portability.Cci/HostEnvironment.cs index 3e9a9f173..f1c0e810b 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/HostEnvironment.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/HostEnvironment.cs @@ -20,13 +20,12 @@ public enum ErrorTreatment { Default, TreatAsWarning, - Ignore + Ignore, } public class HostEnvironment : MetadataReaderHost { private PeReader _reader; - private HashSet> _unresolvedIdentities; private AssemblyIdentity _coreAssemblyIdentity; public HostEnvironment() @@ -48,12 +47,12 @@ public HostEnvironment(INameTable nameTable, IInternFactory internFactory) : base(nameTable, internFactory, 0, null, false) { _reader = new PeReader(this); - _unresolvedIdentities = new HashSet>(); + UnresolvedIdentities = new HashSet>(); } public bool UnifyToLibPath { get; set; } - public ICollection> UnresolvedIdentities { get { return _unresolvedIdentities; } } + public ICollection> UnresolvedIdentities { get; } public bool ResolveInReferringUnitLocation { get; set; } @@ -64,10 +63,14 @@ public HostEnvironment(INameTable nameTable, IInternFactory internFactory) public void AddLibPaths(IEnumerable paths) { if (paths == null) + { return; + } foreach (var path in paths) + { AddLibPath(path); + } } public void Cleanup() @@ -80,7 +83,7 @@ public override IUnit LoadUnitFrom(string location) IUnit unit = _reader.OpenModule( BinaryDocument.GetBinaryDocumentForFile(location, this)); - this.RegisterAsLatest(unit); + RegisterAsLatest(unit); return unit; } @@ -98,10 +101,10 @@ public IAssembly LoadAssemblyFrom(string location) /// The data to be used as the unit public IUnit LoadUnitFrom(string location, Stream stream) { - string fileName = Path.GetFileName(location); - IName name = this.NameTable.GetNameFor(fileName); - StreamDocument document = new StreamDocument(location, name, stream); - IModule unit = _reader.OpenModule(document); + var fileName = Path.GetFileName(location); + var name = NameTable.GetNameFor(fileName); + var document = new StreamDocument(location, name, stream); + var unit = _reader.OpenModule(document); this.RegisterAsLatest(unit); return unit; @@ -117,15 +120,21 @@ public IAssembly LoadAssembly(string assemblyNameOrPath) string path = assemblyNameOrPath; if (File.Exists(path)) - return this.LoadAssemblyFrom(path); + { + return LoadAssemblyFrom(path); + } - foreach (var extension in s_probingExtensions) + foreach (var extension in ProbingExtensions) { path = ProbeLibPaths(assemblyNameOrPath + extension); if (path != null) { var assembly = this.LoadAssembly(path); - if (assembly == null) continue; + if (assembly == null) + { + continue; + } + return assembly; } } @@ -139,31 +148,39 @@ private AssemblyIdentity ProbeLibPaths(AssemblyIdentity identity) { AssemblyIdentity probedIdentity = this.Probe(libPath, identity); if (probedIdentity != null) + { return probedIdentity; + } } - return new AssemblyIdentity(identity, ""); + + return new AssemblyIdentity(identity, string.Empty); } private string ProbeLibPaths(string assemblyPath) { if (File.Exists(assemblyPath)) + { return assemblyPath; + } foreach (var libPath in LibPaths) { string combinedPath = Path.Combine(libPath, assemblyPath); if (File.Exists(combinedPath)) + { return combinedPath; + } } + return null; } // Potential way to unify assemblies based on the current runtime - //public override void ResolvingAssemblyReference(IUnit referringUnit, AssemblyIdentity referencedAssembly) - //{ + // public override void ResolvingAssemblyReference(IUnit referringUnit, AssemblyIdentity referencedAssembly) + // { // IAssemblyReference asmRef = referringUnit.UnitReferences.OfType() // .FirstOrDefault(a => referencedAssembly.Equals(a.UnifiedAssemblyIdentity)); - + // // if (asmRef != null && asmRef.IsRetargetable) // { // string strongName = UnitHelper.StrongName(asmRef); @@ -171,15 +188,14 @@ private string ProbeLibPaths(string assemblyPath) // if (strongName != retargetedName) // { // System.Reflection.AssemblyName name = new System.Reflection.AssemblyName(retargetedName); - + // // referencedAssembly = new AssemblyIdentity(this.NameTable.GetNameFor(name.Name), // name.CultureInfo != null ? name.CultureInfo.Name : "", name.Version, name.GetPublicKeyToken(), ""); // } // } // base.ResolvingAssemblyReference(referringUnit, referencedAssembly); - //} - - private static string[] s_probingExtensions = new string[] + // } + private static readonly string[] ProbingExtensions = new string[] { ".dll", ".ildll", @@ -187,7 +203,8 @@ private string ProbeLibPaths(string assemblyPath) ".winmd", ".exe", ".ilexe", - //".ni.exe" Do these actually exist? + + // ".ni.exe" Do these actually exist? }; protected override AssemblyIdentity Probe(string probeDir, AssemblyIdentity referencedAssembly) @@ -197,28 +214,38 @@ protected override AssemblyIdentity Probe(string probeDir, AssemblyIdentity refe Contract.Requires(referencedAssembly != null); #endif string path = null; - foreach (var extension in s_probingExtensions) + foreach (var extension in ProbingExtensions) { path = Path.Combine(probeDir, referencedAssembly.Name.Value + extension); if (File.Exists(path)) { // Possible that we might find an assembly with a matching extension but without a match identity // or possibly be a native version of the assembly so if that fails we should try other extensions. - var assembly = this.LoadUnitFrom(path) as IAssembly; - if (assembly == null) continue; + if (!(LoadUnitFrom(path) is IAssembly assembly)) + { + continue; + } - if (this.UnifyToLibPath) + if (UnifyToLibPath) { // If Unifying to LibPath then we only verify the assembly name matches. - if (assembly.AssemblyIdentity.Name.UniqueKeyIgnoringCase != referencedAssembly.Name.UniqueKeyIgnoringCase) continue; + if (assembly.AssemblyIdentity.Name.UniqueKeyIgnoringCase != referencedAssembly.Name.UniqueKeyIgnoringCase) + { + continue; + } } else { - if (!assembly.AssemblyIdentity.Equals(referencedAssembly)) continue; + if (!assembly.AssemblyIdentity.Equals(referencedAssembly)) + { + continue; + } } + return assembly.AssemblyIdentity; } } + return null; } @@ -226,7 +253,9 @@ protected override AssemblyIdentity GetCoreAssemblySymbolicIdentity() { // If explicitly set return that identity if (_coreAssemblyIdentity != null) + { return _coreAssemblyIdentity; + } AssemblyIdentity baseCoreAssemblyIdentity = base.GetCoreAssemblySymbolicIdentity(); @@ -234,11 +263,15 @@ protected override AssemblyIdentity GetCoreAssemblySymbolicIdentity() foreach (var assembly in this.LoadedUnits.OfType()) { if (assembly.AssemblyIdentity.Equals(assembly.CoreAssemblySymbolicIdentity)) + { return assembly.AssemblyIdentity; + } // Adjust the base core assembly identity based on what this assembly believes should be if (assembly.AssemblyIdentity.Equals(baseCoreAssemblyIdentity)) + { baseCoreAssemblyIdentity = assembly.CoreAssemblySymbolicIdentity; + } } // Otherwise fallback to CCI's default core assembly loading logic. @@ -251,11 +284,14 @@ public void SetCoreAssembly(AssemblyIdentity coreAssembly) { throw new InvalidOperationException(LocalizedStrings.CoreAssemblyAlreadySet); } + // Lets ignore this if someone passes dummy as nothing good can come from it. We considered making it an error // but in some logical cases (i.e. facades) the CoreAssembly might be dummy and we don't want to start throwing // in a bunch of cases where if we let it go the right thing will happen. if (coreAssembly == Dummy.AssemblyIdentity) + { return; + } _coreAssemblyIdentity = coreAssembly; } @@ -269,20 +305,26 @@ private AssemblyIdentity FindUnifiedAssemblyIdentity(AssemblyIdentity identity) IAssembly asm = this.FindAssembly(identity); if (asm != null && !(asm is Dummy)) + { return asm.AssemblyIdentity; + } // Find assembly match based on simple name only. (It might be worth caching these results if we find them to be too expensive) foreach (var loadedAssembly in this.LoadedUnits.OfType()) { if (loadedAssembly.AssemblyIdentity.Name.UniqueKeyIgnoringCase == identity.Name.UniqueKeyIgnoringCase) + { return loadedAssembly.AssemblyIdentity; + } } - AssemblyIdentity probedIdentity = this.ProbeLibPaths(identity); + var probedIdentity = ProbeLibPaths(identity); if (probedIdentity != null) + { return probedIdentity; + } - return new AssemblyIdentity(identity, ""); + return new AssemblyIdentity(identity, string.Empty); } /// @@ -291,10 +333,14 @@ private AssemblyIdentity FindUnifiedAssemblyIdentity(AssemblyIdentity identity) public override AssemblyIdentity UnifyAssembly(AssemblyIdentity assemblyIdentity) { if (ShouldUnifyToCoreAssembly(assemblyIdentity)) + { return this.CoreAssemblySymbolicIdentity; + } if (this.UnifyToLibPath) - assemblyIdentity = this.FindUnifiedAssemblyIdentity(assemblyIdentity); + { + assemblyIdentity = FindUnifiedAssemblyIdentity(assemblyIdentity); + } return assemblyIdentity; } @@ -305,8 +351,10 @@ public override AssemblyIdentity UnifyAssembly(AssemblyIdentity assemblyIdentity // .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .ver 255:255:255:255 // } - private static readonly byte[] s_ecmaKey = { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }; - private static readonly Version s_winmdBclVersion = new Version(255, 255, 255, 255); + private static readonly byte[] EcmaKey = { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }; + + private static readonly Version WinmdBclVersion = new Version(255, 255, 255, 255); + public bool ShouldUnifyToCoreAssembly(AssemblyIdentity assemblyIdentity) { // Unify any other potential versions of this core assembly to itself. @@ -314,7 +362,9 @@ public bool ShouldUnifyToCoreAssembly(AssemblyIdentity assemblyIdentity) { if (assemblyIdentity.PublicKeyToken == null || !assemblyIdentity.PublicKeyToken.SequenceEqual(this.CoreAssemblySymbolicIdentity.PublicKeyToken)) + { return false; + } return true; } @@ -323,10 +373,15 @@ public bool ShouldUnifyToCoreAssembly(AssemblyIdentity assemblyIdentity) // another facade. if (assemblyIdentity.Name.Value == "mscorlib") { - if (assemblyIdentity.PublicKeyToken == null || !assemblyIdentity.PublicKeyToken.SequenceEqual(s_ecmaKey)) + if (assemblyIdentity.PublicKeyToken == null || !assemblyIdentity.PublicKeyToken.SequenceEqual(EcmaKey)) + { return false; - if (!(assemblyIdentity.Version.Equals(s_winmdBclVersion))) + } + + if (!assemblyIdentity.Version.Equals(WinmdBclVersion)) + { return false; + } return true; } @@ -342,8 +397,10 @@ public override AssemblyIdentity ProbeAssemblyReference(IUnit referringUnit, Ass { // We need to ensure the core assembly is being unified and in some code paths, such as from GetCoreAssemblySymbolicIdentity // it doesn't get properly unified before calling ProbeAssemblyReference - if (this.CoreAssemblySymbolicIdentity.Equals(referencedAssembly)) + if (CoreAssemblySymbolicIdentity.Equals(referencedAssembly)) + { referencedAssembly = UnifyAssembly(referencedAssembly); + } AssemblyIdentity result = null; @@ -351,21 +408,26 @@ public override AssemblyIdentity ProbeAssemblyReference(IUnit referringUnit, Ass { // NOTE: When probing for the core assembly, the referring unit is a dummy unit and thus does not have // a location. - - string referringDir = string.IsNullOrEmpty(referringUnit.Location) ? null + var referringDir = string.IsNullOrEmpty(referringUnit.Location) ? null : Path.GetDirectoryName(Path.GetFullPath(referringUnit.Location)); result = string.IsNullOrEmpty(referringDir) ? null - : this.Probe(referringDir, referencedAssembly); + : Probe(referringDir, referencedAssembly); - if (result != null) return result; + if (result != null) + { + return result; + } } // Probe in the libPaths directories foreach (string libPath in this.LibPaths) { result = this.Probe(libPath, referencedAssembly); - if (result != null) return result; + if (result != null) + { + return result; + } } if (this.ResolveAgainstRunningFramework) @@ -374,7 +436,9 @@ public override AssemblyIdentity ProbeAssemblyReference(IUnit referringUnit, Ass result = base.ProbeAssemblyReference(referringUnit, referencedAssembly); if (result != null && result.Location != null && !result.Location.StartsWith("unknown", StringComparison.Ordinal)) + { return result; + } } var unresolved = new UnresolvedReference(referringUnit, referencedAssembly); @@ -387,11 +451,9 @@ public override AssemblyIdentity ProbeAssemblyReference(IUnit referringUnit, Ass protected virtual void OnUnableToResolve(UnresolvedReference unresolved) { - var unableToResolve = this.UnableToResolve; - if (unableToResolve != null) - unableToResolve(this, unresolved); + UnableToResolve?.Invoke(this, unresolved); - this.UnresolvedIdentities.Add(unresolved); + UnresolvedIdentities.Add(unresolved); } // Overriding this method allows us to read the binaries without blocking the files. The default @@ -407,7 +469,9 @@ public override IBinaryDocumentMemoryBlock OpenBinaryDocument(IBinaryDocument so // call the overload that processes the stream. var streamDocument = sourceDocument as StreamDocument; if (streamDocument != null) + { return UnmanagedBinaryMemoryBlock.CreateUnmanagedBinaryMemoryBlock(streamDocument.Stream, sourceDocument); + } // Otherwise we assume that we can load the data from the location of sourceDocument. try @@ -427,7 +491,9 @@ public override IBinaryDocumentMemoryBlock OpenBinaryDocument(IBinaryDocument so public static string[] SplitPaths(string pathSet) { if (pathSet == null) + { return new string[0]; + } return pathSet.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); } @@ -472,7 +538,9 @@ public ReadOnlyCollection LoadAssemblies(string unsplitContractSet, s // Explicitly set the core assembly if (coreAssemblyFile != null && assemblies.Count > 0) + { SetCoreAssembly(assemblies[0].AssemblyIdentity); + } return assemblies; } @@ -485,12 +553,14 @@ public ErrorTreatment LoadErrorTreatment // False by deafult for backwards compatibility with tools that wire in their own custom handlers. private bool _traceResolutionErrorsAsLoadErrors; + public bool TraceResolutionErrorsAsLoadErrors { get { return _traceResolutionErrorsAsLoadErrors; } + set { if (value != _traceResolutionErrorsAsLoadErrors) @@ -555,16 +625,14 @@ public ReadOnlyCollection LoadAssemblies(IEnumerable paths, A string filePath = ProbeLibPaths(file); if (filePath == null) { - if (logErrorCallback != null) - logErrorCallback(string.Format(CultureInfo.CurrentCulture, "File does not exist {0}", file), LoadErrorTreatment); + logErrorCallback?.Invoke(string.Format(CultureInfo.CurrentCulture, "File does not exist {0}", file), LoadErrorTreatment); continue; } - assembly = this.LoadAssembly(filePath); + assembly = LoadAssembly(filePath); if (assembly == null) { - if (logErrorCallback != null) - logErrorCallback(string.Format(CultureInfo.CurrentCulture, "Failed to load assembly {0}", filePath), LoadErrorTreatment); + logErrorCallback?.Invoke(string.Format(CultureInfo.CurrentCulture, "Failed to load assembly {0}", filePath), LoadErrorTreatment); continue; } @@ -573,8 +641,7 @@ public ReadOnlyCollection LoadAssemblies(IEnumerable paths, A if (assemblySet.Count == 0) { - if (logErrorCallback != null) - logErrorCallback(string.Format(CultureInfo.CurrentCulture, "No assemblies loaded for {0}", string.Join(", ", paths)), LoadErrorTreatment); + logErrorCallback?.Invoke(string.Format(CultureInfo.CurrentCulture, "No assemblies loaded for {0}", string.Join(", ", paths)), LoadErrorTreatment); } return new ReadOnlyCollection(assemblySet); @@ -618,22 +685,22 @@ public IEnumerable LoadAssemblies(IEnumerable ident foreach (var unmappedIdentity in identities) { // Remap the name and clear the location. - AssemblyIdentity identity = new AssemblyIdentity(this.NameTable.GetNameFor(unmappedIdentity.Name.Value), - unmappedIdentity.Culture, unmappedIdentity.Version, unmappedIdentity.PublicKeyToken, ""); + var identity = new AssemblyIdentity(this.NameTable.GetNameFor(unmappedIdentity.Name.Value), + unmappedIdentity.Culture, unmappedIdentity.Version, unmappedIdentity.PublicKeyToken, string.Empty); - AssemblyIdentity matchingIdentity = this.ProbeLibPaths(identity); + var matchingIdentity = this.ProbeLibPaths(identity); var matchingAssembly = this.LoadAssembly(matchingIdentity); if ((matchingAssembly == null || matchingAssembly == Dummy.Assembly) && logErrorOrWarningCallback != null) { - string message = string.Format(CultureInfo.CurrentCulture, "Failed to find or load matching assembly '{0}'.", identity.Name.Value); + var message = string.Format(CultureInfo.CurrentCulture, "Failed to find or load matching assembly '{0}'.", identity.Name.Value); logErrorOrWarningCallback(message, LoadErrorTreatment); continue; } if (!identity.Version.Equals(matchingAssembly.Version) && logErrorOrWarningCallback != null && warnOnVersionMismatch) { - string message = string.Format(CultureInfo.CurrentCulture, "Found '{0}' with version '{1}' instead of '{2}'.", identity.Name.Value, matchingAssembly.Version, identity.Version); + var message = string.Format(CultureInfo.CurrentCulture, "Found '{0}' with version '{1}' instead of '{2}'.", identity.Name.Value, matchingAssembly.Version, identity.Version); logErrorOrWarningCallback(message, ErrorTreatment.TreatAsWarning); } @@ -661,7 +728,7 @@ public IEnumerable LoadAssemblies(IEnumerable ident if (coreIdentity == null) { - throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, LocalizedStrings.CoreAssemblyNotFoundInIdentities, coreAssemblySimpleName)); + throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.CoreAssemblyNotFoundInIdentities, coreAssemblySimpleName)); } identities = Enumerable.Concat(new List() { coreIdentity }, identities.Where(ai => ai != coreIdentity)); @@ -673,12 +740,13 @@ public IEnumerable LoadAssemblies(IEnumerable ident public static IEnumerable GetFilePaths(IEnumerable paths, SearchOption searchOption) { if (searchOption == SearchOption.TopDirectoryOnly) + { return GetFilePaths(paths); + } // expand the path into a list of paths that contains all the subdirectories - Stack unexpandedPaths = new Stack(paths); - - HashSet allPaths = new HashSet(StringComparer.OrdinalIgnoreCase); + var unexpandedPaths = new Stack(paths); + var allPaths = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (var path in paths) { @@ -686,7 +754,9 @@ public static IEnumerable GetFilePaths(IEnumerable paths, Search // if the path did not point to a directory, continue if (!Directory.Exists(path)) + { continue; + } foreach (var dir in Directory.EnumerateDirectories(path, "*.*", SearchOption.AllDirectories)) { @@ -713,7 +783,9 @@ private static IEnumerable GetFilePaths(IEnumerable paths, Actio foreach (var path in paths) { if (path == null) + { continue; + } string resolvedPath = Environment.ExpandEnvironmentVariables(path); @@ -721,17 +793,18 @@ private static IEnumerable GetFilePaths(IEnumerable paths, Actio { perResolvedPathAction(resolvedPath); - for (int extIndex = 0; extIndex < s_probingExtensions.Length; extIndex++) + for (int extIndex = 0; extIndex < ProbingExtensions.Length; extIndex++) { - var searchPattern = "*" + s_probingExtensions[extIndex]; + var searchPattern = "*" + ProbingExtensions[extIndex]; foreach (var file in Directory.EnumerateFiles(resolvedPath, searchPattern)) { yield return file; } } + if (recursive) { - //recursively do the same for sub-folders + // Recursively do the same for sub-folders foreach (var file in GetFilePaths(Directory.EnumerateDirectories(resolvedPath), perResolvedPathAction, recursive)) { yield return file; @@ -753,7 +826,9 @@ private static IEnumerable GetFilePaths(IEnumerable paths, Actio } foreach (var file in files) + { yield return file; + } } else { @@ -808,6 +883,7 @@ public UnresolvedReference(TReferrer referrer, TUnresolved unresolvedReference) } public TReferrer Referrer { get; private set; } + public TUnresolved Unresolved { get; private set; } } } diff --git a/src/lib/Microsoft.Fx.Portability.Cci/TypeExtensions.cs b/src/lib/Microsoft.Fx.Portability.Cci/TypeExtensions.cs index 93cf43eff..e4953d8c7 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/TypeExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/TypeExtensions.cs @@ -41,12 +41,16 @@ public static bool IsDummy(this IDefinition def) public static ITypeDefinition GetDefinitionOrNull(this ITypeReference type) { if (type == null) + { return null; + } ITypeDefinition typeDef = type.ResolvedType; if (typeDef.IsDummy()) + { return null; + } return typeDef; } @@ -58,7 +62,9 @@ public static IEnumerable GetBaseTypesAndInterfaces(this ITypeD ITypeDefinition baseType = bc.GetDefinitionOrNull(); if (baseType != null) + { yield return baseType; + } } foreach (var iface in type.Interfaces) @@ -66,7 +72,9 @@ public static IEnumerable GetBaseTypesAndInterfaces(this ITypeD ITypeDefinition baseType = iface.GetDefinitionOrNull(); if (baseType != null) + { yield return baseType; + } } } @@ -82,8 +90,10 @@ public static IEnumerable GetAllBaseTypes(this ITypeDefinition { yield return baseType; - foreach (ITypeDefinition nextBaseType in GetAllBaseTypes(baseType)) + foreach (var nextBaseType in GetAllBaseTypes(baseType)) + { yield return nextBaseType; + } } } } @@ -100,13 +110,19 @@ public static IEnumerable GetAllInterfaces(this ITypeDefinition // Get all the base types of the interface. foreach (ITypeDefinition nextIfaceRef in GetAllBaseTypes(iface)) + { yield return nextIfaceRef; + } } } foreach (var baseType in GetAllBaseTypes(type)) + { foreach (var iface in GetAllInterfaces(baseType)) + { yield return iface; + } + } } public static IAssembly GetAssembly(this ITypeDefinition type) @@ -115,11 +131,15 @@ public static IAssembly GetAssembly(this ITypeDefinition type) IAssembly assembly = unit as IAssembly; if (assembly != null) + { return assembly; + } IModule module = unit as IModule; if (module != null) + { return module.ContainingAssembly; + } return null; } @@ -130,11 +150,15 @@ public static IAssemblyReference GetAssemblyReference(this ITypeReference type) IAssemblyReference assembly = unit as IAssemblyReference; if (assembly != null) + { return assembly; + } IModuleReference module = unit as IModuleReference; if (module != null) + { return module.ContainingAssembly; + } return null; } @@ -144,17 +168,20 @@ public static IAssemblyReference GetAssemblyReference(this IReference reference) Contract.Requires(reference != null); Contract.Requires(!(reference is Dummy)); - IAssemblyReference assembly = reference as IAssemblyReference; - if (assembly != null) + if (reference is IAssemblyReference assembly) + { return assembly; + } - ITypeReference type = reference as ITypeReference; - if (type != null) + if (reference is ITypeReference type) + { return type.GetAssemblyReference(); + } - ITypeMemberReference member = reference as ITypeMemberReference; - if (member != null) + if (reference is ITypeMemberReference member) + { return member.ContainingType.GetAssemblyReference(); + } throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnknownIReference, reference.GetType().FullName)); } @@ -177,24 +204,23 @@ public static bool IsGenericInstance(this IMethodReference method) public static bool IsWindowsRuntimeAssembly(this IAssemblyReference assembly) { if (assembly == null) + { return false; + } // ContainsForeignTypes == AssemblyFlag 0x200 == windowsruntime bit - if (assembly.ContainsForeignTypes) - return true; - - return false; + return assembly.ContainsForeignTypes; } public static bool IsWindowsRuntimeType(this ITypeReference type) { - IAssemblyReference assemblyRef = type.GetAssemblyReference(); + var assemblyRef = type.GetAssemblyReference(); return assemblyRef.IsWindowsRuntimeAssembly(); } public static bool IsWindowsRuntimeMember(this ITypeMemberReference member) { - IAssemblyReference assemblyRef = member.GetAssemblyReference(); + var assemblyRef = member.GetAssemblyReference(); return assemblyRef.IsWindowsRuntimeAssembly(); } @@ -205,56 +231,65 @@ public static bool IsFunctionPointer(this ITypeReference type) public static string GetTypeName(this ITypeReference type, bool includeNamespace = true) { - TypeNameFormatter formatter = new TypeNameFormatter(); - NameFormattingOptions options = NameFormattingOptions.OmitTypeArguments | NameFormattingOptions.UseReflectionStyleForNestedTypeNames; + var formatter = new TypeNameFormatter(); + var options = NameFormattingOptions.OmitTypeArguments | NameFormattingOptions.UseReflectionStyleForNestedTypeNames; if (!includeNamespace) + { options |= NameFormattingOptions.OmitContainingNamespace; + } string name = formatter.GetTypeName(type, options); return name; } + public static string GetTypeName(this ITypeReference type, NameFormattingOptions options) { - TypeNameFormatter formatter = new TypeNameFormatter(); + var formatter = new TypeNameFormatter(); string name = formatter.GetTypeName(type, options); return name; } public static INamespaceDefinition GetNamespace(this ITypeDefinition type) { - INamespaceTypeDefinition nsType = type as INamespaceTypeDefinition; - if (nsType != null) + if (type is INamespaceTypeDefinition nsType) + { return nsType.ContainingNamespace; + } - INestedTypeDefinition ntType = type as INestedTypeDefinition; - if (ntType != null) + if (type is INestedTypeDefinition ntType) + { return GetNamespace(ntType.ContainingTypeDefinition); + } return null; } public static string GetNamespaceName(this ITypeReference type) { - INamespaceTypeReference nsType = type as INamespaceTypeReference; - if (nsType != null) + if (type is INamespaceTypeReference nsType) + { return TypeHelper.GetNamespaceName(nsType.ContainingUnitNamespace, NameFormattingOptions.None); + } - INestedTypeReference ntType = type as INestedTypeReference; - if (ntType != null) + if (type is INestedTypeReference ntType) + { return GetNamespaceName(ntType.ContainingType); + } - return ""; + return string.Empty; } public static string Name(this ITypeDefinition type) { - INamespaceTypeDefinition nsType = type as INamespaceTypeDefinition; - if (nsType != null) + if (type is INamespaceTypeDefinition nsType) + { return nsType.Name.Value; + } - INestedTypeDefinition nType = type as INestedTypeDefinition; - if (nType != null) + if (type is INestedTypeDefinition nType) + { return nType.Name.Value; + } throw new NotImplementedException(LocalizedStrings.CalledNameOnUnsupportedDefinition); } @@ -263,23 +298,27 @@ public static string FullName(this IReference reference) { Contract.Requires(reference != null); - ITypeReference type = reference as ITypeReference; - if (type != null) + if (reference is ITypeReference type) + { return TypeHelper.GetTypeName(type, NameFormattingOptions.TypeParameters); + } - ITypeMemberReference member = reference as ITypeMemberReference; - if (member != null) + if (reference is ITypeMemberReference member) + { return MemberHelper.GetMemberSignature(member, NameFormattingOptions.TypeParameters | NameFormattingOptions.Signature); + } - IUnitNamespaceReference ns = reference as IUnitNamespaceReference; - if (ns != null) + if (reference is IUnitNamespaceReference ns) + { return TypeHelper.GetNamespaceName(ns, NameFormattingOptions.None); + } - INamedEntity named = reference as INamedEntity; - if (named != null) + if (reference is INamedEntity named) + { return named.Name.Value; + } - Contract.Assert(false, String.Format(CultureInfo.CurrentCulture, LocalizedStrings.FellThroughCasesIn, "TypeExtensions.FullName()", reference.GetType())); + Contract.Assert(false, string.Format(CultureInfo.CurrentCulture, LocalizedStrings.FellThroughCasesIn, "TypeExtensions.FullName()", reference.GetType())); return LocalizedStrings.UnknownReferenceType; } @@ -292,21 +331,25 @@ public static string UniqueId(this IReference reference) { Contract.Requires(reference != null); - ITypeReference type = reference as ITypeReference; - if (type != null) + if (reference is ITypeReference type) + { return type.DocId(); + } - ITypeMemberReference member = reference as ITypeMemberReference; - if (member != null) + if (reference is ITypeMemberReference member) + { return member.DocId(); + } - IUnitNamespaceReference ns = reference as IUnitNamespaceReference; - if (ns != null) + if (reference is IUnitNamespaceReference ns) + { return ns.DocId(); + } - IAssemblyReference assembly = reference as IAssemblyReference; - if (assembly != null) + if (reference is IAssemblyReference assembly) + { return assembly.DocId(); + } // Include the hash code as well to make it unique so we can use this for a key return LocalizedStrings.UnknownReferenceType + reference.GetHashCode().ToString(CultureInfo.InvariantCulture); @@ -317,7 +360,9 @@ public static IEnumerable GetAllNamespaces(this IAssembly yield return assembly.NamespaceRoot; foreach (var ns in assembly.NamespaceRoot.GetNamespaces(true)) + { yield return ns; + } } public static IEnumerable GetNamespaces(this INamespaceDefinition ns, bool recursive = true) @@ -329,7 +374,9 @@ public static IEnumerable GetNamespaces(this INamespaceDef if (recursive) { foreach (var nn in nestedNs.GetNamespaces(recursive)) + { yield return nn; + } } } } @@ -342,9 +389,10 @@ public static IEnumerable GetTypes(this INamespaceDefi { types = ns.Members.Select(nsMember => { - INamespaceAliasForType nsAlias = nsMember as INamespaceAliasForType; - if (nsAlias != null) + if (nsMember is INamespaceAliasForType nsAlias) + { nsMember = nsAlias.AliasedType.ResolvedType as INamespaceTypeDefinition; + } return nsMember as INamespaceTypeDefinition; }).Where(t => t != null); @@ -353,23 +401,30 @@ public static IEnumerable GetTypes(this INamespaceDefi { types = ns.Members.OfType(); } + return types; } public static IEnumerable GetAllMembers(this ITypeDefinition type) { foreach (var m in type.Members) + { yield return m; + } if (type.IsInterface) { foreach (var m in GetAllMembersFromInterfaces(type)) + { yield return m; + } } else { foreach (var m in GetAllMembersBaseType(type)) + { yield return m; + } } } @@ -378,14 +433,16 @@ public static IEnumerable GetAllMembersBaseType(this ITyp ITypeReference baseTypeRef = type.BaseClasses.FirstOrDefault(); if (baseTypeRef == null || TypeHelper.TypesAreEquivalent(baseTypeRef, type.PlatformType.SystemObject)) + { yield break; + } ITypeDefinition baseType = baseTypeRef.ResolvedType; - //Contract.Assert(baseType != Dummy.Type); - foreach (var m in GetAllMembers(baseType)) + { yield return m; + } } public static IEnumerable GetAllMembersFromInterfaces(this ITypeDefinition type) @@ -393,10 +450,11 @@ public static IEnumerable GetAllMembersFromInterfaces(thi foreach (ITypeReference iface in type.Interfaces) { ITypeDefinition ifaceType = iface.ResolvedType; - //Contract.Assert(ifaceType != Dummy.Type); foreach (var m in ifaceType.Members) + { yield return m; + } } } @@ -407,25 +465,30 @@ public static bool AreEquivalent(this ITypeReference type, string typeName) public static ITypeReference UnWrap(this ITypeReference reference) { - IPointerTypeReference pointer = reference as IPointerTypeReference; - if (pointer != null) + if (reference is IPointerTypeReference pointer) + { return pointer.TargetType.UnWrap(); + } - IArrayTypeReference array = reference as IArrayTypeReference; - if (array != null) + if (reference is IArrayTypeReference array) + { return array.ElementType.UnWrap(); + } - IModifiedTypeReference modified = reference as IModifiedTypeReference; - if (modified != null) + if (reference is IModifiedTypeReference modified) + { return modified.UnmodifiedType.UnWrap(); + } - ISpecializedNestedTypeReference specialized = reference as ISpecializedNestedTypeReference; - if (specialized != null) + if (reference is ISpecializedNestedTypeReference specialized) + { return specialized.UnspecializedVersion.UnWrap(); + } - IGenericTypeInstanceReference instantiation = reference as IGenericTypeInstanceReference; - if (instantiation != null) + if (reference is IGenericTypeInstanceReference instantiation) + { return instantiation.GenericType.UnWrap(); + } Contract.Assert(reference is INamedTypeReference || reference is INestedTypeReference @@ -433,7 +496,7 @@ public static ITypeReference UnWrap(this ITypeReference reference) || reference is IGenericTypeParameterReference || reference is IGenericMethodParameterReference || reference is IFunctionPointerTypeReference, - string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnexpectedTypeReference, (reference?.GetType()?.FullName ?? "null"))); + string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnexpectedTypeReference, reference?.GetType()?.FullName ?? "null")); return reference; } @@ -441,29 +504,35 @@ public static ITypeReference UnWrap(this ITypeReference reference) public static T UnWrapMember(this T member) where T : ITypeMemberReference { - IGenericMethodInstanceReference genericMethod = member as IGenericMethodInstanceReference; - if (genericMethod != null) + if (member is IGenericMethodInstanceReference genericMethod) + { return (T)genericMethod.GenericMethod.UnWrapMember(); + } - ISpecializedNestedTypeReference type = member as ISpecializedNestedTypeReference; - if (type != null) + if (member is ISpecializedNestedTypeReference type) + { return (T)type.UnspecializedVersion.UnWrapMember(); + } - ISpecializedMethodReference method = member as ISpecializedMethodReference; - if (method != null) + if (member is ISpecializedMethodReference method) + { return (T)method.UnspecializedVersion.UnWrapMember(); + } - ISpecializedFieldReference field = member as ISpecializedFieldReference; - if (field != null) + if (member is ISpecializedFieldReference field) + { return (T)field.UnspecializedVersion.UnWrapMember(); + } - ISpecializedPropertyDefinition property = member as ISpecializedPropertyDefinition; - if (property != null) + if (member is ISpecializedPropertyDefinition property) + { return (T)property.UnspecializedVersion.UnWrapMember(); + } - ISpecializedEventDefinition evnt = member as ISpecializedEventDefinition; - if (evnt != null) + if (member is ISpecializedEventDefinition evnt) + { return (T)evnt.UnspecializedVersion.UnWrapMember(); + } return member; } @@ -476,24 +545,34 @@ public static bool IsPropertyOrEventAccessor(this IMethodDefinition method) public static AccessorType GetAccessorType(this IMethodDefinition methodDefinition) { if (!methodDefinition.IsSpecialName) + { return AccessorType.None; + } foreach (var p in methodDefinition.ContainingTypeDefinition.Properties) { if (p.Getter != null && p.Getter.ResolvedMethod.InternedKey == methodDefinition.InternedKey) + { return AccessorType.PropertyGetter; + } if (p.Setter != null && p.Setter.ResolvedMethod.InternedKey == methodDefinition.InternedKey) + { return AccessorType.PropertySetter; + } } foreach (var e in methodDefinition.ContainingTypeDefinition.Events) { if (e.Adder != null && e.Adder.ResolvedMethod.InternedKey == methodDefinition.InternedKey) + { return AccessorType.EventAdder; + } if (e.Remover != null && e.Remover.ResolvedMethod.InternedKey == methodDefinition.InternedKey) + { return AccessorType.EventRemover; + } } return AccessorType.None; @@ -506,17 +585,16 @@ where a.Type.FullName() == "System.Runtime.Versioning.TargetFrameworkAttribute" select a).FirstOrDefault(); if (tfmAttribute == null) + { return string.Empty; + } - var nameArgument = tfmAttribute.Arguments.FirstOrDefault() as IMetadataConstant; - if (nameArgument == null) - return string.Empty; - - var name = nameArgument.Value as string; - if (name == null) + if (!(tfmAttribute.Arguments.FirstOrDefault() is IMetadataConstant nameArgument)) + { return string.Empty; + } - return name; + return !(nameArgument.Value is string name) ? string.Empty : name; } public static bool IsReferenceAssembly(this IAssembly assembly) @@ -524,20 +602,21 @@ public static bool IsReferenceAssembly(this IAssembly assembly) return assembly.AssemblyAttributes.Any(a => a.Type.FullName() == "System.Runtime.CompilerServices.ReferenceAssemblyAttribute"); } - private static Dictionary s_tokenNames = new Dictionary() + private static readonly Dictionary TokenNames = new Dictionary() { - {"b77a5c561934e089", "ECMA"}, - {"b03f5f7f11d50a3a", "DEVDIV"}, - {"7cec85d7bea7798e", "SLPLAT"}, - {"31bf3856ad364e35", "SILVERLIGHT"}, - {"24eec0d8c86cda1e", "PHONE"}, + { "b77a5c561934e089", "ECMA" }, + { "b03f5f7f11d50a3a", "DEVDIV" }, + { "7cec85d7bea7798e", "SLPLAT" }, + { "31bf3856ad364e35", "SILVERLIGHT" }, + { "24eec0d8c86cda1e", "PHONE" }, }; public static string MapPublicKeyTokenToName(string publicKeyToken) { - string name; - if (!s_tokenNames.TryGetValue(publicKeyToken.ToLower(), out name)) + if (!TokenNames.TryGetValue(publicKeyToken.ToLower(), out var name)) + { name = publicKeyToken; + } return name; } @@ -559,7 +638,7 @@ public static string GetPublicKeyToken(this IAssemblyReference assembly) public static string GetPublicKeyToken(this AssemblyIdentity identity) { - return identity.PublicKeyToken.Aggregate("", (s, b) => s += b.ToString("x2", CultureInfo.InvariantCulture)); + return identity.PublicKeyToken.Aggregate(string.Empty, (s, b) => s += b.ToString("x2", CultureInfo.InvariantCulture)); } public static bool IsFrameworkAssembly(this AssemblyIdentity identity) @@ -575,7 +654,9 @@ public static bool IsFrameworkAssembly(this AssemblyIdentity identity) public static bool IsFacade(this IAssembly assembly) { if (assembly.GetAllTypes().Any(t => t.Name.Value != "")) + { return false; + } return true; } @@ -607,14 +688,14 @@ public static bool IsEditorBrowseableStateNever(this ICustomAttribute attribute) return false; } - IMetadataConstant singleArgument = attribute.Arguments.Single() as IMetadataConstant; + var singleArgument = attribute.Arguments.Single() as IMetadataConstant; if (singleArgument == null || !(singleArgument.Value is int)) { return false; } - if (EditorBrowsableState.Never != (EditorBrowsableState)singleArgument.Value) + if ((EditorBrowsableState)singleArgument.Value != EditorBrowsableState.Never) { return false; } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberDependency.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberDependency.cs index b85fd7a74..8d2169a91 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberDependency.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberDependency.cs @@ -18,16 +18,20 @@ internal class MemberDependency private bool _isPrimitive; /// - /// This represents the assembly that is calling the member + /// Gets or sets the assembly that is calling the member /// public AssemblyInfo CallingAssembly { get; set; } /// - /// This represents the assembly in which the member is defined + /// Gets or sets the assembly in which the member is defined /// public AssemblyReferenceInformation DefinedInAssemblyIdentity { - get { return _definedInAssemblyIdentity; } + get + { + return _definedInAssemblyIdentity; + } + set { _definedInAssemblyIdentity = value; @@ -36,11 +40,15 @@ public AssemblyReferenceInformation DefinedInAssemblyIdentity } /// - /// This indicates whether or not the dependency is a primitive type + /// Gets or sets a value indicating whether or not the dependency is a primitive type /// public bool IsPrimitive { - get { return _isPrimitive; } + get + { + return _isPrimitive; + } + set { _isPrimitive = value; @@ -50,7 +58,11 @@ public bool IsPrimitive public string MemberDocId { - get { return _memberDocId; } + get + { + return _memberDocId; + } + set { _memberDocId = value; @@ -60,7 +72,11 @@ public string MemberDocId public string TypeDocId { - get { return _typeDocId; } + get + { + return _typeDocId; + } + set { _typeDocId = value; @@ -75,9 +91,7 @@ public override string ToString() public override bool Equals(object obj) { - var other = obj as MemberDependency; - - if (other == null) + if (!(obj is MemberDependency other)) { return false; } @@ -95,6 +109,7 @@ public override int GetHashCode() _hashCode = ((DefinedInAssemblyIdentity?.ToString() ?? string.Empty) + (MemberDocId ?? string.Empty) + IsPrimitive.ToString()).GetHashCode() ^ CallingAssembly.GetHashCode(); _hashComputed = true; } + return _hashCode; } } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberModifiedMetadata.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberModifiedMetadata.cs index f65054559..ca47cc0ae 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberModifiedMetadata.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberModifiedMetadata.cs @@ -6,6 +6,7 @@ namespace Microsoft.Fx.Portability.Analyzer internal class MemberModifiedMetadata { public bool IsRequired { get; } + public MemberMetadataInfo Metadata { get; } public MemberModifiedMetadata(bool isRequired, MemberMetadataInfo metadata) diff --git a/src/lib/Microsoft.Fx.Portability.Offline/OfflineApiPortService.cs b/src/lib/Microsoft.Fx.Portability.Offline/OfflineApiPortService.cs index 23bf09940..2afcad90f 100644 --- a/src/lib/Microsoft.Fx.Portability.Offline/OfflineApiPortService.cs +++ b/src/lib/Microsoft.Fx.Portability.Offline/OfflineApiPortService.cs @@ -31,7 +31,7 @@ public OfflineApiPortService(IApiCatalogLookup lookup, IRequestAnalyzer requestA _mapper = mapper; _reportWriters = reportWriters; _defaultTargets = new HashSet(targetNameParser.DefaultTargets); - _searcher = new StringContainsSearch(lookup); + _searcher = new StringContainsSearcher(lookup); _apiRecommendations = apiRecommendations; } diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs index fecd75832..7779a11d7 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs @@ -20,6 +20,7 @@ internal class ExcelOpenXmlOutputWriter internal static class ColumnWidths { internal const double Targets = 15; + internal static class SummaryPage { internal const double AssemblyName = 40; @@ -126,7 +127,7 @@ private void AddStylesheet(WorkbookPart wb) CellFormats = new CellFormats(format1, format2), Fills = new Fills(fill1, fill2), CellStyles = new CellStyles(cellstyle), - Borders = new Borders(border) + Borders = new Borders(border), }; wb.AddNewPart(); diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/HyperlinkCell.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/HyperlinkCell.cs index 3e7e0af09..7b4669f8a 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/HyperlinkCell.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/HyperlinkCell.cs @@ -8,7 +8,9 @@ namespace Microsoft.Fx.OpenXmlExtensions internal class HyperlinkCell { public string DisplayString { get; set; } + public Uri Url { get; set; } + public uint? StyleIndex { get; set; } } } diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelSpreadsheetExtensions.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs similarity index 100% rename from src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelSpreadsheetExtensions.cs rename to src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Html/CompatibilityResultsModel.cs b/src/lib/Microsoft.Fx.Portability.Reports.Html/CompatibilityResultsModel.cs index c70b7c48c..b858597d9 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Html/CompatibilityResultsModel.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Html/CompatibilityResultsModel.cs @@ -9,9 +9,13 @@ namespace Microsoft.Fx.Portability.Reports.Html public class CompatibilityResultsModel { public string Name { get; } + public string Description { get; } + public IEnumerable>> Breaks { get; } + public int WarningThreshold { get; } + public int ErrorThreshold { get; } public CompatibilityResultsModel(string name, string description, IEnumerable>> breaks, int warningThreshold, int errorThreshold) diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Html/CompatibilitySummaryModel.cs b/src/lib/Microsoft.Fx.Portability.Reports.Html/CompatibilitySummaryModel.cs index c02ac4617..17f777dbd 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Html/CompatibilitySummaryModel.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Html/CompatibilitySummaryModel.cs @@ -10,7 +10,9 @@ namespace Microsoft.Fx.Portability.Reports.Html public class CompatibilitySummaryModel { public IDictionary> Breaks { get; } + public AssemblyInfo Assembly { get; } + public ReportingResult ReportingResult { get; } public CompatibilitySummaryModel(IDictionary> breaks, AssemblyInfo assembly, ReportingResult reportingResult) diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs index 6efed9cae..7bf325ad9 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs @@ -12,6 +12,7 @@ using System; using Microsoft.Fx.Portability.Reports.Html; using Microsoft.Fx.Portability.Reports.Html.Resources; + using static System.FormattableString; namespace Microsoft.Fx.Portability.Reports diff --git a/src/lib/Microsoft.Fx.Portability/Analyzer/IDependencyInfo.cs b/src/lib/Microsoft.Fx.Portability/Analyzer/IDependencyInfo.cs index ba6d52c3b..4a8671d8f 100644 --- a/src/lib/Microsoft.Fx.Portability/Analyzer/IDependencyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/Analyzer/IDependencyInfo.cs @@ -9,8 +9,11 @@ namespace Microsoft.Fx.Portability.Analyzer public interface IDependencyInfo { IDictionary> Dependencies { get; } + IEnumerable AssembliesWithErrors { get; } + IDictionary> UnresolvedAssemblies { get; } + IEnumerable UserAssemblies { get; } } } diff --git a/src/lib/Microsoft.Fx.Portability/ApiDefinition.cs b/src/lib/Microsoft.Fx.Portability/ApiDefinition.cs index 8fa1658fb..8291685b8 100644 --- a/src/lib/Microsoft.Fx.Portability/ApiDefinition.cs +++ b/src/lib/Microsoft.Fx.Portability/ApiDefinition.cs @@ -18,11 +18,13 @@ public string DocId get { return _docId ?? string.Empty; } set { _docId = value; } } + public string ReturnType { get { return _returnType ?? string.Empty; } set { _returnType = value; } } + public string Name { get { return _name ?? string.Empty; } diff --git a/src/lib/Microsoft.Fx.Portability/BreakingChangeDependency.cs b/src/lib/Microsoft.Fx.Portability/BreakingChangeDependency.cs index d588ce8ef..f8058456f 100644 --- a/src/lib/Microsoft.Fx.Portability/BreakingChangeDependency.cs +++ b/src/lib/Microsoft.Fx.Portability/BreakingChangeDependency.cs @@ -9,12 +9,16 @@ namespace Microsoft.Fx.Portability public class BreakingChangeDependency : IEquatable { public MemberInfo Member { get; set; } + public BreakingChange Break { get; set; } + public AssemblyInfo DependantAssembly { get; set; } public bool Equals(BreakingChangeDependency other) { - return (Member.Equals(other.Member) && (Break.CompareTo(other.Break) == 0) && DependantAssembly.Equals(other.DependantAssembly)); + return Member.Equals(other.Member) + && (Break.CompareTo(other.Break) == 0) + && DependantAssembly.Equals(other.DependantAssembly); } } } diff --git a/src/lib/Microsoft.Fx.Portability/IApiPortOptions.cs b/src/lib/Microsoft.Fx.Portability/IApiPortOptions.cs index 9052e4eec..7cc68bccd 100644 --- a/src/lib/Microsoft.Fx.Portability/IApiPortOptions.cs +++ b/src/lib/Microsoft.Fx.Portability/IApiPortOptions.cs @@ -16,15 +16,25 @@ public interface IApiPortOptions /// Value: true if the file was explicitly specified and false otherwise. /// ImmutableDictionary InputAssemblies { get; } + IEnumerable IgnoredAssemblyFiles { get; } + AnalyzeRequestFlags RequestFlags { get; } + IEnumerable Targets { get; } + IEnumerable OutputFormats { get; } + IEnumerable BreakingChangeSuppressions { get; } + string ServiceEndpoint { get; } + string OutputFileName { get; } + IEnumerable InvalidInputFiles { get; } + bool OverwriteOutputFile { get; } + IEnumerable ReferencedNuGetPackages { get; } } } diff --git a/src/lib/Microsoft.Fx.Portability/IApiPortService.cs b/src/lib/Microsoft.Fx.Portability/IApiPortService.cs index 49de14e40..cb9934d34 100644 --- a/src/lib/Microsoft.Fx.Portability/IApiPortService.cs +++ b/src/lib/Microsoft.Fx.Portability/IApiPortService.cs @@ -10,12 +10,19 @@ namespace Microsoft.Fx.Portability public interface IApiPortService { Task>> GetTargetsAsync(); + Task> SendAnalysisAsync(AnalyzeRequest a); + Task>> SendAnalysisAsync(AnalyzeRequest a, IEnumerable format); + Task> GetApiInformationAsync(string docId); + Task>> SearchFxApiAsync(string query, int? top = null); + Task>> GetResultFormatsAsync(); + Task> GetDefaultResultFormatAsync(); + Task>> QueryDocIdsAsync(IEnumerable docIds); } } diff --git a/src/lib/Microsoft.Fx.Portability/IProgressReporter.cs b/src/lib/Microsoft.Fx.Portability/IProgressReporter.cs index fc6ea4cf0..c983fc09f 100644 --- a/src/lib/Microsoft.Fx.Portability/IProgressReporter.cs +++ b/src/lib/Microsoft.Fx.Portability/IProgressReporter.cs @@ -9,11 +9,15 @@ namespace Microsoft.Fx.Portability public interface IProgressReporter : IDisposable { void ReportIssue(string issue); + IProgressTask StartTask(string taskName, int totalUnits); + IProgressTask StartTask(string taskName); + IReadOnlyCollection Issues { get; } void Suspend(); + void Resume(); } } diff --git a/src/lib/Microsoft.Fx.Portability/IProgressTask.cs b/src/lib/Microsoft.Fx.Portability/IProgressTask.cs index 72d2c0b1e..57aaa6043 100644 --- a/src/lib/Microsoft.Fx.Portability/IProgressTask.cs +++ b/src/lib/Microsoft.Fx.Portability/IProgressTask.cs @@ -8,6 +8,7 @@ namespace Microsoft.Fx.Portability public interface IProgressTask : IDisposable { void ReportUnitComplete(); + void Abort(); } } diff --git a/src/lib/Microsoft.Fx.Portability/ITargetMapper.cs b/src/lib/Microsoft.Fx.Portability/ITargetMapper.cs index 801c20087..234401c0f 100644 --- a/src/lib/Microsoft.Fx.Portability/ITargetMapper.cs +++ b/src/lib/Microsoft.Fx.Portability/ITargetMapper.cs @@ -9,8 +9,11 @@ namespace Microsoft.Fx.Portability public interface ITargetMapper { string GetAlias(string targetName); + ICollection GetNames(string aliasName); + ICollection Aliases { get; } + IEnumerable GetTargetNames(IEnumerable targets, bool alwaysIncludeVersion = false); } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/ApiInfoStorage.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/ApiInfoStorage.cs index 18257061d..b1f02e07c 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/ApiInfoStorage.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/ApiInfoStorage.cs @@ -10,15 +10,20 @@ namespace Microsoft.Fx.Portability.ObjectModel public class ApiInfoStorage { public string DocId { get; set; } + public string Type { get; set; } + public string Name { get; set; } + public string FullName { get; set; } /// /// DocId of the parent. Null if the Api does not have a parent. /// public string Parent { get; set; } + public IReadOnlyCollection Targets { get; set; } + public IReadOnlyCollection Metadata { get; set; } } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/ApiMetadataStorage.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/ApiMetadataStorage.cs index 8281cbe91..d227c473d 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/ApiMetadataStorage.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/ApiMetadataStorage.cs @@ -8,6 +8,7 @@ namespace Microsoft.Fx.Portability.ObjectModel public class ApiMetadataStorage { public string MetadataKey { get; set; } + public string Value { get; set; } } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs index 43c51196f..7e85c1c7c 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs @@ -20,6 +20,7 @@ public sealed class AssemblyInfo : IComparable public string AssemblyIdentity { get { return _assemblyIdentity; } + set { _assemblyIdentity = value; @@ -28,7 +29,7 @@ public string AssemblyIdentity } /// - /// Assembly location + /// Gets or sets the assembly location /// /// Do not serialize location and send it to service. [JsonIgnore] @@ -36,7 +37,11 @@ public string AssemblyIdentity public string FileVersion { - get { return _fileVersion; } + get + { + return _fileVersion; + } + set { _fileVersion = value; @@ -47,6 +52,7 @@ public string FileVersion public string TargetFrameworkMoniker { get { return _targetFrameworkVersion; } + set { _targetFrameworkVersion = value; diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/AvailableTarget.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/AvailableTarget.cs index 923eb17c1..26977cecc 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/AvailableTarget.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/AvailableTarget.cs @@ -16,9 +16,13 @@ public AvailableTarget() } public string Name { get; set; } + public string Description { get; set; } + public Version Version { get; set; } + public IEnumerable ExpandedTargets { get; set; } + public bool IsSet { get; set; } public override string ToString() diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/CompatibilityRange.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/CompatibilityRange.cs index efc2a996e..50ee35465 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/CompatibilityRange.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/CompatibilityRange.cs @@ -11,10 +11,15 @@ namespace Microsoft.Fx.Portability.ObjectModel public class CompatibilityRange { public string FrameworkName { get; set; } + public Version StartVersion { get; set; } + public Version EndVersion { get; set; } + public Version LatestVersion { get; set; } + public Version DefaultVersion { get; set; } + public bool IsRetargeting { get; set; } } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/DiagnosticAnalyzerInfo.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/DiagnosticAnalyzerInfo.cs index 0125b9a2d..86bdc4156 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/DiagnosticAnalyzerInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/DiagnosticAnalyzerInfo.cs @@ -13,16 +13,21 @@ namespace Microsoft.Fx.Portability.ObjectModel #endif public class DiagnosticAnalyzerInfo { - private static readonly Regex s_regEx = new Regex(@"(\d+)", RegexOptions.Compiled); + private static readonly Regex DiagnosticIdRegex = new Regex(@"(\d+)", RegexOptions.Compiled); public string AnalyzerName { get; set; } + public string Id { get; set; } + public ICollection CompatibilityRanges { get; set; } + public bool IsCompatibilityDiagnostic { get; set; } + public ICollection SupportedLanguages { get; set; } /// - /// Returns the integer number value from the Id string property or a -1 if an integer value cannot be returned. + /// Returns the integer number value from the Id string property or a + /// -1 if an integer value cannot be returned. /// public int GetIdNumber() { @@ -31,7 +36,7 @@ public int GetIdNumber() return -1; } - var regExMatches = s_regEx.Match(Id); + var regExMatches = DiagnosticIdRegex.Match(Id); return regExMatches.Success ? int.Parse(regExMatches.Captures[0].Value, CultureInfo.InvariantCulture) : -1; } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/DotNetCatalog.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/DotNetCatalog.cs index 55ceb2f82..94f14588f 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/DotNetCatalog.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/DotNetCatalog.cs @@ -9,9 +9,13 @@ namespace Microsoft.Fx.Portability.ObjectModel public class DotNetCatalog { public DateTimeOffset LastModified { get; set; } + public string BuiltBy { get; set; } + public IReadOnlyCollection Apis { get; set; } + public IReadOnlyCollection FrameworkAssemblyIdenties { get; set; } + public IReadOnlyCollection SupportedTargets { get; set; } } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/IApiCatalogLookup.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/IApiCatalogLookup.cs index f1ada9d9f..86beaea87 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/IApiCatalogLookup.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/IApiCatalogLookup.cs @@ -10,19 +10,33 @@ namespace Microsoft.Fx.Portability.ObjectModel public interface IApiCatalogLookup { DateTimeOffset LastModified { get; } + string BuiltBy { get; } + ApiDefinition GetApiDefinition(string docId); + IEnumerable DocIds { get; } + IEnumerable GetAllTargets(); + string GetRecommendedChange(string docId); + string GetSourceCompatibilityEquivalent(string docId); + FrameworkName GetLatestVersion(string targetIdentifier); + IEnumerable GetPublicTargets(); + Version GetVersionIntroducedIn(string docId, FrameworkName target); + bool IsFrameworkAssembly(string assemblyIdentity); + bool IsFrameworkMember(string docId); + bool IsMemberInTarget(string docId, FrameworkName targetName, out Version introducedVersion); + bool IsMemberInTarget(string docId, FrameworkName targetName); + IEnumerable GetSupportedVersions(string docId); /// diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/IStorage.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/IStorage.cs index 10028311d..4995c1d2a 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/IStorage.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/IStorage.cs @@ -9,9 +9,13 @@ namespace Microsoft.Fx.Portability.ObjectModel public interface IStorage { Task SaveToBlobAsync(AnalyzeRequest analyzeRequest, string submissionId); + Task RetrieveRequestAsync(string uniqueId); + Task> RetrieveSubmissionIdsAsync(); + Task AddJobToQueueAsync(string submissionId); + IEnumerable GetProjectSubmissions(); } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfo.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfo.cs index 252a0ddbb..6ef1b2f00 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfo.cs @@ -10,6 +10,7 @@ namespace Microsoft.Fx.Portability.ObjectModel public class IgnoreAssemblyInfo : IEquatable { public string AssemblyIdentity { get; set; } + public IEnumerable TargetsIgnored { get; set; } // If specific targets to ignore for aren't specified, then assume the assembly should be ignored everywhere @@ -17,9 +18,17 @@ public class IgnoreAssemblyInfo : IEquatable public bool Equals(IgnoreAssemblyInfo other) { - if (other == null) return false; - if (!AssemblyIdentity.Equals(other.AssemblyIdentity, StringComparison.OrdinalIgnoreCase)) return false; - if ((TargetsIgnored == null || TargetsIgnored.Count() == 0)) + if (other == null) + { + return false; + } + + if (!AssemblyIdentity.Equals(other.AssemblyIdentity, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + if (TargetsIgnored == null || TargetsIgnored.Count() == 0) { if (other.TargetsIgnored != null && other.TargetsIgnored.Count() > 0) { @@ -30,7 +39,11 @@ public bool Equals(IgnoreAssemblyInfo other) { // We could just look to see that all of the targets ignored by either object are ignored by the other, but this way // will prevent duplicates which is desirable since the merge method should make it easy for user to not have duplicate targets - if (TargetsIgnored.Count() != (other.TargetsIgnored == null ? 0 : other.TargetsIgnored.Count())) return false; + if (TargetsIgnored.Count() != (other.TargetsIgnored == null ? 0 : other.TargetsIgnored.Count())) + { + return false; + } + var sortedTargetsEnum = TargetsIgnored.OrderBy(s => s).GetEnumerator(); var sortedOtherTargetsEnum = other.TargetsIgnored.OrderBy(s => s).GetEnumerator(); while (sortedTargetsEnum.MoveNext() && sortedOtherTargetsEnum.MoveNext()) @@ -38,6 +51,7 @@ public bool Equals(IgnoreAssemblyInfo other) if (!sortedTargetsEnum.Current.Equals(sortedOtherTargetsEnum.Current, StringComparison.OrdinalIgnoreCase)) return false; } } + return true; } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/MemberInfo.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/MemberInfo.cs index c5e17b26b..cc048bdf4 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/MemberInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/MemberInfo.cs @@ -17,11 +17,15 @@ public sealed class MemberInfo : IComparable private string _typeDocId; /// - /// This represents the assembly in which the member is defined + /// Gets or sets the assembly in which the member is defined /// public string DefinedInAssemblyIdentity { - get { return _targetName; } + get + { + return _targetName; + } + set { _targetName = value; @@ -31,7 +35,11 @@ public string DefinedInAssemblyIdentity public string MemberDocId { - get { return _memberDocId; } + get + { + return _memberDocId; + } + set { _memberDocId = value; @@ -41,7 +49,11 @@ public string MemberDocId public string TypeDocId { - get { return _typeDocId; } + get + { + return _typeDocId; + } + set { _typeDocId = value; @@ -50,6 +62,7 @@ public string TypeDocId } public string RecommendedChanges { get; set; } + public string SourceCompatibleChange { get; set; } public List TargetStatus { get; set; } @@ -64,9 +77,10 @@ public override string ToString() public override bool Equals(object obj) { - MemberInfo other = obj as MemberInfo; - if (other == null) + if (!(obj is MemberInfo other)) + { return false; + } return StringComparer.Ordinal.Equals(MemberDocId, other.MemberDocId) && StringComparer.Ordinal.Equals(DefinedInAssemblyIdentity, other.DefinedInAssemblyIdentity); @@ -79,6 +93,7 @@ public override int GetHashCode() _hashCode = ((DefinedInAssemblyIdentity ?? string.Empty) + (MemberDocId ?? string.Empty)).GetHashCode(); _hashComputed = true; } + return _hashCode; } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/TargetInformation.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/TargetInformation.cs index 0ada750a2..f0cefa49f 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/TargetInformation.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/TargetInformation.cs @@ -11,17 +11,17 @@ namespace Microsoft.Fx.Portability.ObjectModel { public class TargetInformation { - private static readonly ISet s_EmptyTargets = new HashSet(); - private static readonly ICollection s_EmptyVersions = new List(); - private static readonly string s_ListSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator + " "; + private static readonly ISet EmptyTargets = new HashSet(); + private static readonly ICollection EmptyVersions = new List(); + private static readonly string ListSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator + " "; private ISet _expandedTargets; private ICollection _versions; public TargetInformation() { - _expandedTargets = s_EmptyTargets; - _versions = s_EmptyVersions; + _expandedTargets = EmptyTargets; + _versions = EmptyVersions; } public string Name { get; set; } @@ -29,20 +29,21 @@ public TargetInformation() public IEnumerable ExpandedTargets { get { return _expandedTargets; } - set - { - _expandedTargets = new HashSet(value, StringComparer.OrdinalIgnoreCase); - } + set { _expandedTargets = new HashSet(value, StringComparer.OrdinalIgnoreCase); } } public IEnumerable AvailableVersions { - get { return _versions; } + get + { + return _versions; + } + set { if (value == null) { - _versions = s_EmptyVersions; + _versions = EmptyVersions; } else { @@ -55,7 +56,7 @@ public override string ToString() { if (ExpandedTargets.Any()) { - return string.Format(CultureInfo.CurrentCulture, LocalizedStrings.TargetInformationGroups, Name, string.Join(s_ListSeparator, ExpandedTargets)); + return string.Format(CultureInfo.CurrentCulture, LocalizedStrings.TargetInformationGroups, Name, string.Join(ListSeparator, ExpandedTargets)); } else { @@ -65,9 +66,10 @@ public override string ToString() public override bool Equals(object obj) { - var other = obj as TargetInformation; - - if (other == null) return false; + if (!(obj is TargetInformation other)) + { + return false; + } return string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase) && _expandedTargets.SetEquals(other._expandedTargets); @@ -79,11 +81,11 @@ public override int GetHashCode() const int HashMultiplier = 23; int hash = HashSeed; - hash = hash * HashMultiplier + (Name ?? string.Empty).GetHashCode(); + hash = (hash * HashMultiplier) + (Name ?? string.Empty).GetHashCode(); foreach (var target in ExpandedTargets) { - hash = hash * HashMultiplier + target.GetHashCode(); + hash = (hash * HashMultiplier) + target.GetHashCode(); } return hash; diff --git a/src/lib/Microsoft.Fx.Portability/PortabilityAnalyzerException.cs b/src/lib/Microsoft.Fx.Portability/PortabilityAnalyzerException.cs index 84b5a2b4a..94754b301 100644 --- a/src/lib/Microsoft.Fx.Portability/PortabilityAnalyzerException.cs +++ b/src/lib/Microsoft.Fx.Portability/PortabilityAnalyzerException.cs @@ -7,7 +7,14 @@ namespace Microsoft.Fx.Portability { public class PortabilityAnalyzerException : Exception { - public PortabilityAnalyzerException(string message) : base(message) { } - public PortabilityAnalyzerException(string message, Exception innerException) : base(message, innerException) { } + public PortabilityAnalyzerException(string message) + : base(message) + { + } + + public PortabilityAnalyzerException(string message, Exception innerException) + : base(message, innerException) + { + } } } diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/IFileSystem.cs b/src/lib/Microsoft.Fx.Portability/Reporting/IFileSystem.cs index 9a2ad66ac..791915f33 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/IFileSystem.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/IFileSystem.cs @@ -9,12 +9,19 @@ namespace Microsoft.Fx.Portability.Reporting public interface IFileSystem { string ChangeFileExtension(string filename, string newExtension); + string CombinePaths(params string[] paths); + bool FileExists(string path); + IEnumerable FilesInDirectory(string directoryPath); + string GetDirectoryNameFromPath(string path); + string GetFileExtension(string filename); + Stream CreateFile(string path); + IEnumerable SearchPathForFile(string filename); } } diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/IReportWriter.cs b/src/lib/Microsoft.Fx.Portability/Reporting/IReportWriter.cs index 0a94df4de..126e2b5fc 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/IReportWriter.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/IReportWriter.cs @@ -9,6 +9,7 @@ namespace Microsoft.Fx.Portability.Reporting public interface IReportWriter { ResultFormatInformation Format { get; } + void WriteStream(Stream stream, AnalyzeResponse response); } } diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingInfo.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingInfo.cs index a55fba040..12295b777 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingInfo.cs @@ -10,6 +10,7 @@ namespace Microsoft.Fx.Portability.Reporting.ObjectModel public class MissingInfo { public string DocId { get; set; } + public string RecommendedChanges { get; protected set; } public MissingInfo(string docId) @@ -24,8 +25,7 @@ public override int GetHashCode() public override bool Equals(object obj) { - MissingInfo other = obj as MissingInfo; - return other != null && StringComparer.Ordinal.Equals(other.DocId, DocId); + return obj is MissingInfo other && StringComparer.Ordinal.Equals(other.DocId, DocId); } protected static string GenerateTargetStatusMessage(Version version) diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingMemberInfo.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingMemberInfo.cs index e9d5bb3b4..104078525 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingMemberInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingMemberInfo.cs @@ -12,22 +12,29 @@ public class MissingMemberInfo : MissingInfo { private readonly HashSet _usedInAssemblies; - public IEnumerable UsedIn { get { return _usedInAssemblies; } } + public IEnumerable UsedIn { get; } + + public int Uses + { + get { return _usedInAssemblies.Count; } + } - public int Uses { get { return _usedInAssemblies.Count; } } public string MemberName { get; set; } - public IEnumerable TargetStatus { get; set; } + + public IEnumerable TargetStatus { get; set; } + public IEnumerable TargetVersionStatus { get; set; } + public void IncrementUsage(AssemblyInfo sourceAssembly) { _usedInAssemblies.Add(sourceAssembly); } - public MissingMemberInfo(AssemblyInfo sourceAssembly, string DocId, List targetStatus, string recommendedChanges) - : base(DocId) + public MissingMemberInfo(AssemblyInfo sourceAssembly, string docId, List targetStatus, string recommendedChanges) + : base(docId) { RecommendedChanges = recommendedChanges; - MemberName = DocId; + MemberName = docId; TargetStatus = targetStatus?.Select(GenerateTargetStatusMessage).ToList() ?? Enumerable.Empty(); TargetVersionStatus = new List(targetStatus ?? Enumerable.Empty()); diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/ReportingResult.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/ReportingResult.cs index 607dd603e..9fd0fc66a 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/ReportingResult.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/ReportingResult.cs @@ -11,24 +11,25 @@ namespace Microsoft.Fx.Portability.Reporting.ObjectModel { public class ReportingResult { - private readonly AnalyzeRequestFlags _requestFlags; private readonly HashSet _missingTypes = new HashSet(); private readonly Dictionary, MemberInfo> _types; private readonly Dictionary> _unresolvedUserAssemblies = new Dictionary>(); private readonly HashSet _assembliesWithError = new HashSet(); - private readonly IList _targets; - private List _perAssemblyUsage; private Dictionary _assemblyNameMap; - public AnalyzeRequestFlags RequestFlags { get { return _requestFlags; } } - public IList Targets { get { return _targets; } } - public string SubmissionId { get; private set; } + public AnalyzeRequestFlags RequestFlags { get; } + + public IList Targets { get; } + + public string SubmissionId { get; } + public IList NuGetPackages { get; set; } + public ReportingResult(IList targets, IEnumerable types, string submissionId, AnalyzeRequestFlags requestFlags) { - _targets = targets; - _requestFlags = requestFlags; + Targets = targets; + RequestFlags = requestFlags; SubmissionId = submissionId; _types = types.ToDictionary(key => Tuple.Create(key.DefinedInAssemblyIdentity, key.MemberDocId), value => value); } @@ -53,24 +54,24 @@ public IEnumerable GetAssemblyUsageInfo() return _perAssemblyUsage != null ? _perAssemblyUsage.ToList() : Enumerable.Empty(); } - public void AddMissingDependency(AssemblyInfo SourceAssembly, MemberInfo missingDependency, string recommendedChanges) + public void AddMissingDependency(AssemblyInfo sourceAssembly, MemberInfo missingDependency, string recommendedChanges) { MissingTypeInfo typeInfo; try { - var type = _types[Tuple.Create(missingDependency.DefinedInAssemblyIdentity, (missingDependency.TypeDocId ?? missingDependency.MemberDocId))]; - typeInfo = new MissingTypeInfo(SourceAssembly, type.MemberDocId, type.TargetStatus, type.RecommendedChanges); + var type = _types[Tuple.Create(missingDependency.DefinedInAssemblyIdentity, missingDependency.TypeDocId ?? missingDependency.MemberDocId)]; + typeInfo = new MissingTypeInfo(sourceAssembly, type.MemberDocId, type.TargetStatus, type.RecommendedChanges); } catch (KeyNotFoundException) { - typeInfo = new MissingTypeInfo(SourceAssembly, missingDependency.TypeDocId ?? missingDependency.MemberDocId, missingDependency.TargetStatus, recommendedChanges); + typeInfo = new MissingTypeInfo(sourceAssembly, missingDependency.TypeDocId ?? missingDependency.MemberDocId, missingDependency.TargetStatus, recommendedChanges); } // If we already have an entry for this type, get it. if (_missingTypes.Any(mt => mt.TypeName == typeInfo.TypeName)) { typeInfo = _missingTypes.First(mt => mt.TypeName == typeInfo.TypeName); - typeInfo.IncrementUsage(SourceAssembly); + typeInfo.IncrementUsage(sourceAssembly); } else { @@ -78,12 +79,12 @@ public void AddMissingDependency(AssemblyInfo SourceAssembly, MemberInfo missing } // If we did not receive a member entry, it means the entire type is missing -- flag it accordingly - if (missingDependency.MemberDocId.StartsWith("M:", System.StringComparison.OrdinalIgnoreCase) || - missingDependency.MemberDocId.StartsWith("F:", System.StringComparison.OrdinalIgnoreCase) || - missingDependency.MemberDocId.StartsWith("P:", System.StringComparison.OrdinalIgnoreCase)) + if (missingDependency.MemberDocId.StartsWith("M:", StringComparison.OrdinalIgnoreCase) || + missingDependency.MemberDocId.StartsWith("F:", StringComparison.OrdinalIgnoreCase) || + missingDependency.MemberDocId.StartsWith("P:", StringComparison.OrdinalIgnoreCase)) { - MissingMemberInfo memberInfo = new MissingMemberInfo(SourceAssembly, missingDependency.MemberDocId, missingDependency.TargetStatus, recommendedChanges); - typeInfo.AddMissingMember(memberInfo, SourceAssembly); + var memberInfo = new MissingMemberInfo(sourceAssembly, missingDependency.MemberDocId, missingDependency.TargetStatus, recommendedChanges); + typeInfo.AddMissingMember(memberInfo, sourceAssembly); } else { diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/PlatformUsageInfo.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs similarity index 100% rename from src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/PlatformUsageInfo.cs rename to src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs diff --git a/src/lib/Microsoft.Fx.Portability/ResultFormatInformation.cs b/src/lib/Microsoft.Fx.Portability/ResultFormatInformation.cs index b83d4835c..5190aa5b2 100644 --- a/src/lib/Microsoft.Fx.Portability/ResultFormatInformation.cs +++ b/src/lib/Microsoft.Fx.Portability/ResultFormatInformation.cs @@ -8,7 +8,9 @@ namespace Microsoft.Fx.Portability public class ResultFormatInformation { public string DisplayName { get; set; } + public string MimeType { get; set; } + public string FileExtension { get; set; } public override bool Equals(object obj) diff --git a/src/lib/Microsoft.Fx.Portability/ServiceResponse.cs b/src/lib/Microsoft.Fx.Portability/ServiceResponse.cs index 4b61638a5..d2de04f4b 100644 --- a/src/lib/Microsoft.Fx.Portability/ServiceResponse.cs +++ b/src/lib/Microsoft.Fx.Portability/ServiceResponse.cs @@ -8,6 +8,7 @@ namespace Microsoft.Fx.Portability public class ServiceResponse { public T Response { get; private set; } + public ServiceHeaders Headers { get; private set; } public ServiceResponse(T response) diff --git a/src/lib/Microsoft.Fx.Portability/StringContainsSearcher.cs b/src/lib/Microsoft.Fx.Portability/StringContainsSearcher.cs index 468cdb637..0ac1363a2 100644 --- a/src/lib/Microsoft.Fx.Portability/StringContainsSearcher.cs +++ b/src/lib/Microsoft.Fx.Portability/StringContainsSearcher.cs @@ -9,11 +9,11 @@ namespace Microsoft.Fx.Portability { - public class StringContainsSearch : ISearcher + public class StringContainsSearcher : ISearcher { private readonly IApiCatalogLookup _lookup; - public StringContainsSearch(IApiCatalogLookup lookup) + public StringContainsSearcher(IApiCatalogLookup lookup) { _lookup = lookup; } diff --git a/src/lib/Microsoft.Fx.Portability/Utils/JsonConverters/JsonMultiDictionaryConverter.cs b/src/lib/Microsoft.Fx.Portability/Utils/JsonConverters/JsonMultiDictionaryConverter.cs index 4299dff32..5b18f0d59 100644 --- a/src/lib/Microsoft.Fx.Portability/Utils/JsonConverters/JsonMultiDictionaryConverter.cs +++ b/src/lib/Microsoft.Fx.Portability/Utils/JsonConverters/JsonMultiDictionaryConverter.cs @@ -17,6 +17,7 @@ internal class JsonMultiDictionaryConverter : JsonConverter Value { get; set; } } diff --git a/stylecop.json b/stylecop.json index 9d5bd1ae1..87b94b97b 100644 --- a/stylecop.json +++ b/stylecop.json @@ -2,6 +2,7 @@ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", "settings": { "documentationRules": { + "fileNamingConvention": "stylecop", "documentExposedElements": false, "documentInternalElements": false, "companyName": "Microsoft", @@ -22,6 +23,7 @@ "namingRules": {}, "orderingRules": { "systemUsingDirectivesFirst": false, + "blankLinesBetweenUsingGroups": "require", "usingDirectivesPlacement": "outsideNamespace", "elementOrder": [ "kind", diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngine.NuGetPackageInfo.Tests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineNuGetPackageInfoTests.cs similarity index 98% rename from tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngine.NuGetPackageInfo.Tests.cs rename to tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineNuGetPackageInfoTests.cs index d4ee154ce..63d2e62cb 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngine.NuGetPackageInfo.Tests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineNuGetPackageInfoTests.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Runtime.Versioning; using Xunit; + using static Microsoft.Fx.Portability.Tests.TestData.TestFrameworks; namespace Microsoft.Fx.Portability.Tests.Analysis @@ -17,7 +18,7 @@ namespace Microsoft.Fx.Portability.Tests.Analysis /// /// Tests GetNuGetPackageInfo for AnalysisEngine /// - public class AnalysisEngineTestsNuGetPackageInfo + public class AnalysisEngineNuGetPackageInfoTests { /// /// Tests that given a set of assemblies, the correct nuget package is returned. @@ -42,9 +43,11 @@ public static void TestGetNugetPackageInfo() var packagesList = new[] { - new NuGetPackageInfo(packageId, new Dictionary() { + new NuGetPackageInfo(packageId, new Dictionary() + { {Windows80, nugetPackageWin80Version }, - { NetStandard16, nugetPackageNetStandardVersion} }) + { NetStandard16, nugetPackageNetStandardVersion}, + }) }; packageFinder.TryFindPackages(nugetPackageAssembly.AssemblyIdentity, targets, out var packages) diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs index fcf5528bf..b02929853 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs @@ -432,6 +432,7 @@ public static void FilterDependencies() var mi2_usedIn = result[mi2]; Assert.True(mi2_usedIn.Contains(userAsm3) && !mi2_usedIn.Contains(userAsm2)); } + private static void TestBreakingChangeWithoutFixedEntry(Version version, bool noBreakingChangesExpected) { TestBreakingChange(version, GenerateTestRecommendationsWithoutFixedEntry(), noBreakingChangesExpected, null, Enumerable.Empty()); diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs index 8005ca378..ecaf4dc20 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs @@ -111,6 +111,7 @@ public TestHandler(Func converter) { _converter = converter; } + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return Task.FromResult(_converter(request)); diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoComparerTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoComparerTests.cs index a08da1c6a..ded897c8a 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoComparerTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoComparerTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Runtime.Versioning; using Xunit; + using static Microsoft.Fx.Portability.Tests.TestData.TestFrameworks; namespace Microsoft.Fx.Portability.Tests.ObjectModel diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs index 4a87ceb3c..16b9afb39 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs @@ -12,7 +12,7 @@ namespace Microsoft.Fx.Portability.Tests { - public class TargetMapTest + public class TargetMapTests { [Fact] public static void UnknownTarget() diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestDotNetCatalog.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestDotNetCatalog.cs index 3024e648f..9b9c2b412 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestDotNetCatalog.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestDotNetCatalog.cs @@ -3,19 +3,20 @@ using Microsoft.Fx.Portability.ObjectModel; using System; + using static Microsoft.Fx.Portability.Tests.TestData.TestFrameworks; namespace Microsoft.Fx.Portability.Tests.TestData { public class TestDotNetCatalog : DotNetCatalog { - private static readonly string[] s_frameworkIdentities = new[] { + private static readonly string[] FrameworkIdentities = new[] { "System.Collections, PublicKeyToken=b03f5f7f11d50a3a", "System.Collections.Concurrent, PublicKeyToken=b03f5f7f11d50a3a", "System.Collections.NonGeneric, PublicKeyToken=b03f5f7f11d50a3a" }; - private static readonly TargetInfo[] s_testSupportedTargets = new[] { + private static readonly TargetInfo[] TestSupportedTargets = new[] { new TargetInfo { DisplayName = Windows80, IsReleased = true }, new TargetInfo { DisplayName = Windows81, IsReleased = true }, new TargetInfo { DisplayName = NetCore50, IsReleased = true }, @@ -30,8 +31,8 @@ public TestDotNetCatalog() LastModified = new DateTimeOffset(2015, 12, 2, 11, 23, 01, TimeSpan.FromHours(7)); BuiltBy = "Test Machine"; Apis = GetApis(); - FrameworkAssemblyIdenties = s_frameworkIdentities; - SupportedTargets = s_testSupportedTargets; + FrameworkAssemblyIdenties = FrameworkIdentities; + SupportedTargets = TestSupportedTargets; } private ApiInfoStorage[] GetApis() @@ -44,7 +45,7 @@ private ApiInfoStorage[] GetApis() DocId = "N:System.Collections", FullName = "System.Collections", Name = "System.Collections", - Type = "", + Type = string.Empty, Parent = null, Targets = targets11 }, @@ -52,7 +53,7 @@ private ApiInfoStorage[] GetApis() DocId = "N:System.Collections.Concurrent", FullName = "System.Collections.Concurrent", Name = "System.Collections.Concurrent", - Type = "", + Type = string.Empty, Parent = null, Targets = targets40 }, @@ -60,7 +61,7 @@ private ApiInfoStorage[] GetApis() DocId = "T:System.Collections.Concurrent.ConcurrentBag`1", FullName = "System.Collections.Concurrent.ConcurrentBag", Name = "ConcurrentBag", - Type = "", + Type = string.Empty, Parent = "N:System.Collections.Concurrent", Targets = targets40 }, From fd2e594878ac0b4a87f2e40c04a8160e479ebf4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Nils=20Kuklau?= Date: Wed, 19 Sep 2018 23:14:08 +0200 Subject: [PATCH 05/17] Handle resources DLLs (#699) They don't have any AssemblyReferences and therefore won't resolve System.Object. --- .../DependencyFinderEngineHelper.cs | 1 + .../SystemObjectFinder.cs | 4 +++ ...Fx.Portability.MetadataReader.Tests.csproj | 2 +- .../SystemObjectFinderTests.cs | 30 +++++++++++++++++++ ...sourceAssembliesGetSkipped_NoReferences.il | 4 +++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Tests/ResourceAssembliesGetSkipped_NoReferences.il diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs index 3fd5d1c43..f192fc1e9 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs @@ -4,6 +4,7 @@ using Microsoft.Fx.Portability.ObjectModel; using System; using System.Collections.Generic; +using System.Linq; using System.Reflection.Metadata; namespace Microsoft.Fx.Portability.Analyzer diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs index 53e4ee75c..bfcd54b0e 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs @@ -32,6 +32,10 @@ public SystemObjectFinder(IDependencyFilter assemblyFilter) /// public AssemblyReferenceInformation GetSystemRuntimeAssemblyInformation(MetadataReader reader) { + // this is probably a resources DLL and doesn't need inspection + if (!reader.AssemblyReferences.Any() && !reader.MemberReferences.Any()) + return null; + var microsoftAssemblies = reader.AssemblyReferences .Select(handle => { diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Microsoft.Fx.Portability.MetadataReader.Tests.csproj b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Microsoft.Fx.Portability.MetadataReader.Tests.csproj index 991de33ef..a8e92112c 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Microsoft.Fx.Portability.MetadataReader.Tests.csproj +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Microsoft.Fx.Portability.MetadataReader.Tests.csproj @@ -43,4 +43,4 @@ - \ No newline at end of file + diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs index be2e89b2a..94bc94795 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs @@ -61,5 +61,35 @@ public void NetstandardReferencesOnly() Assert.Equal("cc7b13ffcd2ddd51", assemblyInfo.PublicKeyToken); } } + + /// + /// Test that doesn't throw on + /// assemblies that don't reference System.Object, but also don't + /// reference anything else. This is typically the case for resource + /// assemblies (e.g., for localization). + /// + [Fact] + public void ResourceAssembliesGetSkipped() + { + var objectFinder = new SystemObjectFinder(new DotNetFrameworkFilter()); + var file = TestAssembly.Create("ResourceAssembliesGetSkipped_NoReferences.il", _output); + + using (var stream = file.OpenRead()) + using (var peFile = new PEReader(stream)) + { + var metadataReader = peFile.GetMetadataReader(); + + var ex = Record.Exception(() => + { + var assemblyInfo = objectFinder.GetSystemRuntimeAssemblyInformation(metadataReader); + + // we shouldn't receive anything back + Assert.Null(assemblyInfo); + }); + + // this should not throw + Assert.Null(ex); + } + } } } diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Tests/ResourceAssembliesGetSkipped_NoReferences.il b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Tests/ResourceAssembliesGetSkipped_NoReferences.il new file mode 100644 index 000000000..14ef1cbd6 --- /dev/null +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Tests/ResourceAssembliesGetSkipped_NoReferences.il @@ -0,0 +1,4 @@ +.assembly NoReferences +{ + .ver 1:0:0:0 +} From 91b4478478f3dd6cb4e54b375a97e6c399348561 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Wed, 19 Sep 2018 17:29:04 -0700 Subject: [PATCH 06/17] Check if the assembly itself is a known location for System.Object (#710) --- .../DependencyFinderEngineHelper.cs | 50 ++++++++++------- .../SystemObjectNotFoundException.cs | 26 --------- .../MetadataReaderExtensions.cs | 21 ++++++- .../ReflectionMetadataDependencyInfo.cs | 10 +--- .../Resources/LocalizedStrings.Designer.cs | 3 +- .../Resources/LocalizedStrings.resx | 3 +- .../SystemObjectFinder.cs | 21 +++---- .../SystemObjectNotFoundException.cs | 19 +++++++ .../Microsoft.Fx.Portability/TargetMapper.cs | 2 +- .../ManagedMetadataReaderTests.cs | 19 ++++++- .../SystemObjectFinderTests.cs | 39 +++++++++---- .../TestAssembly.cs | 55 +++++++++++++++---- 12 files changed, 174 insertions(+), 94 deletions(-) delete mode 100644 src/lib/Microsoft.Fx.Portability.MetadataReader/Exceptions/SystemObjectNotFoundException.cs create mode 100644 src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectNotFoundException.cs diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs index f192fc1e9..da5a1a923 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs @@ -45,12 +45,6 @@ public DependencyFinderEngineHelper(IDependencyFilter assemblyFilter, MetadataRe public void ComputeData() { - // Primitives need to have their assembly set, so we search for a - // reference to System.Object that is considered a possible - // framework assembly and use that for any primitives that don't - // have an assembly - var systemObjectAssembly = _objectFinder.GetSystemRuntimeAssemblyInformation(_reader); - var provider = new MemberMetadataInfoTypeProvider(_reader); // Get type references @@ -79,27 +73,41 @@ public void ComputeData() } } - // Get member references - foreach (var handle in _reader.MemberReferences) + if (_reader.MemberReferences.Any()) { - try + // Primitives need to have their assembly set, so we search for a + // reference to System.Object that is considered a possible + // framework assembly and use that for any primitives that don't + // have an assembly + if (_objectFinder.TryGetSystemRuntimeAssemblyInformation(_reader, out var systemObjectAssembly)) { - var entry = _reader.GetMemberReference(handle); - - var memberReferenceMemberDependency = GetMemberReferenceMemberDependency(entry, systemObjectAssembly); - if (memberReferenceMemberDependency != null) + // Get member references + foreach (var handle in _reader.MemberReferences) { - MemberDependency.Add(memberReferenceMemberDependency); + try + { + var entry = _reader.GetMemberReference(handle); + + var memberReferenceMemberDependency = GetMemberReferenceMemberDependency(entry, systemObjectAssembly); + if (memberReferenceMemberDependency != null) + { + MemberDependency.Add(memberReferenceMemberDependency); + } + } + catch (BadImageFormatException) + { + // Some obfuscators will inject dead types that break decompilers + // (for example, types that serve as each others' scopes). + // + // For portability/compatibility analysis purposes, though, + // we can skip such malformed references and just analyze those + // that we can successfully decode. + } } } - catch (BadImageFormatException) + else { - // Some obfuscators will inject dead types that break decompilers - // (for example, types that serve as each others' scopes). - // - // For portability/compatibility analysis purposes, though, - // we can skip such malformed references and just analyze those - // that we can successfully decode. + throw new SystemObjectNotFoundException(); } } } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/Exceptions/SystemObjectNotFoundException.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/Exceptions/SystemObjectNotFoundException.cs deleted file mode 100644 index 58beb2d1f..000000000 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/Exceptions/SystemObjectNotFoundException.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Fx.Portability.Analyzer.Resources; -using Microsoft.Fx.Portability.ObjectModel; -using System.Collections.Generic; -using System.Globalization; - -namespace Microsoft.Fx.Portability.Analyzer.Exceptions -{ - /// - /// Exception thrown when assembly containing - /// cannot be found. - /// - public class SystemObjectNotFoundException : PortabilityAnalyzerException - { - public SystemObjectNotFoundException(IEnumerable assemblies) - : base(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.MissingSystemObjectAssembly, - string.Join(", ", assemblies))) - { - AssembliesReferenced = assemblies; - } - - public IEnumerable AssembliesReferenced { get; } - } -} diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs index 29db7a8d3..edb72747e 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs @@ -18,9 +18,28 @@ public static AssemblyReferenceInformation FormatAssemblyInfo(this MetadataReade return metadataReader.FormatAssemblyInfo(metadataReader.GetAssemblyDefinition()); } + public static bool TryGetCurrentAssemblyName(this MetadataReader metadataReader, out string name) + { + if (metadataReader.IsAssembly) + { + name = metadataReader.GetString(metadataReader.GetAssemblyDefinition().Name); + return true; + } + else + { + name = null; + return false; + } + } + + public static string GetAssemblyName(this MetadataReader metadataReader, AssemblyReference assemblyReference) + { + return metadataReader.GetString(assemblyReference.Name); + } + public static AssemblyReferenceInformation FormatAssemblyInfo(this MetadataReader metadataReader, AssemblyReference assemblyReference) { - var name = metadataReader.GetString(assemblyReference.Name); + var name = metadataReader.GetAssemblyName(assemblyReference); return metadataReader.FormatAssemblyInfo(name, assemblyReference.Culture, assemblyReference.PublicKeyOrToken, assemblyReference.Version); } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs index edb0e998a..220956c62 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.Fx.Portability.Analyzer.Exceptions; using Microsoft.Fx.Portability.Analyzer.Resources; using Microsoft.Fx.Portability.ObjectModel; using System; @@ -107,10 +106,9 @@ private void FindDependencies(IProgressReporter progressReport) }); // Clear out unresolved dependencies that were resolved during processing - ICollection collection; foreach (var assembly in _userAssemblies) { - _unresolvedAssemblies.TryRemove(assembly.AssemblyIdentity, out collection); + _unresolvedAssemblies.TryRemove(assembly.AssemblyIdentity, out _); } } @@ -220,11 +218,7 @@ public ConcurrentHashSet(IEqualityComparer comparer) public void CopyTo(T[] array, int arrayIndex) => Keys.CopyTo(array, arrayIndex); - public bool Remove(T item) - { - byte b; - return TryRemove(item, out b); - } + public bool Remove(T item) => TryRemove(item, out _); IEnumerator IEnumerable.GetEnumerator() => Keys.GetEnumerator(); diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/Resources/LocalizedStrings.Designer.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/Resources/LocalizedStrings.Designer.cs index a6038fb7f..3bea44359 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/Resources/LocalizedStrings.Designer.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/Resources/LocalizedStrings.Designer.cs @@ -107,8 +107,7 @@ internal static string MetadataParsingExceptionMessage { } /// - /// Looks up a localized string similar to Cannot locate assembly information for System.Object. Microsoft assemblies found are: - ///{0}. + /// Looks up a localized string similar to Cannot locate assembly information for System.Object.. /// internal static string MissingSystemObjectAssembly { get { diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/Resources/LocalizedStrings.resx b/src/lib/Microsoft.Fx.Portability.MetadataReader/Resources/LocalizedStrings.resx index a757a5ac1..7fb66f79c 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/Resources/LocalizedStrings.resx +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/Resources/LocalizedStrings.resx @@ -133,8 +133,7 @@ An unexpected error was encountered while parsing the metadata for the PE file located at {0}. - Cannot locate assembly information for System.Object. Microsoft assemblies found are: -{0} + Cannot locate assembly information for System.Object. More parameters were required than are available diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs index bfcd54b0e..9ba916aa0 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.Fx.Portability.Analyzer.Exceptions; using Microsoft.Fx.Portability.ObjectModel; using System; using System.Collections.Generic; @@ -30,11 +29,13 @@ public SystemObjectFinder(IDependencyFilter assemblyFilter) /// /// Tries to locate the assembly containing . /// - public AssemblyReferenceInformation GetSystemRuntimeAssemblyInformation(MetadataReader reader) + public bool TryGetSystemRuntimeAssemblyInformation(MetadataReader reader, out AssemblyReferenceInformation assemblyReference) { - // this is probably a resources DLL and doesn't need inspection - if (!reader.AssemblyReferences.Any() && !reader.MemberReferences.Any()) - return null; + if (reader.TryGetCurrentAssemblyName(out var name) && s_systemObjectAssemblies.Contains(name)) + { + assemblyReference = reader.FormatAssemblyInfo(); + return true; + } var microsoftAssemblies = reader.AssemblyReferences .Select(handle => @@ -50,12 +51,12 @@ public AssemblyReferenceInformation GetSystemRuntimeAssemblyInformation(Metadata if (matchingAssembly != default(AssemblyReferenceInformation)) { - return matchingAssembly; - } - else - { - throw new SystemObjectNotFoundException(microsoftAssemblies); + assemblyReference = matchingAssembly; + return true; } + + assemblyReference = null; + return false; } } } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectNotFoundException.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectNotFoundException.cs new file mode 100644 index 000000000..9bdd87c0e --- /dev/null +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectNotFoundException.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Fx.Portability.Analyzer.Resources; + +namespace Microsoft.Fx.Portability.Analyzer +{ + /// + /// Exception thrown when assembly containing + /// cannot be found. + /// + public class SystemObjectNotFoundException : PortabilityAnalyzerException + { + public SystemObjectNotFoundException() + : base(LocalizedStrings.MissingSystemObjectAssembly) + { + } + } +} diff --git a/src/lib/Microsoft.Fx.Portability/TargetMapper.cs b/src/lib/Microsoft.Fx.Portability/TargetMapper.cs index 4b04efd42..8d0c6fbe3 100644 --- a/src/lib/Microsoft.Fx.Portability/TargetMapper.cs +++ b/src/lib/Microsoft.Fx.Portability/TargetMapper.cs @@ -53,7 +53,7 @@ private static bool IsValidPath(string path) try { // This will throw if a path is invalid - return path != null && Path.GetFullPath(path) != null; + return !string.IsNullOrWhiteSpace(path) && Path.GetFullPath(path) != null; } catch (ArgumentException) { diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs index 1f2348083..513ebf682 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.Fx.Portability.Analyzer; -using Microsoft.Fx.Portability.Analyzer.Exceptions; using Microsoft.Fx.Portability.ObjectModel; using NSubstitute; using System; @@ -240,6 +239,24 @@ public void ThrowsSystemObjectNotFoundException() Assert.IsType(exception.InnerException); } + [Fact] + public void AssemblyWithNoReferencesIsSkipped() + { + var dependencyFilter = Substitute.For(); + dependencyFilter.IsFrameworkAssembly(Arg.Any()).Returns(false); + var dependencyFinder = new ReflectionMetadataDependencyFinder(dependencyFilter, new SystemObjectFinder(dependencyFilter)); + var file = TestAssembly.Create("ResourceAssembliesGetSkipped_NoReferences.il", _output); + var progressReporter = Substitute.For(); + + var dependencies = dependencyFinder.FindDependencies(new[] { file }, progressReporter); + + Assert.Empty(dependencies.AssembliesWithErrors); + Assert.Empty(dependencies.UnresolvedAssemblies); + var assembly = Assert.Single(dependencies.UserAssemblies); + + Assert.Equal("NoReferences, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", assembly.AssemblyIdentity); + } + private static IEnumerable> EmptyProjectMemberDocId() { yield return Tuple.Create("M:System.Diagnostics.DebuggableAttribute.#ctor(System.Diagnostics.DebuggableAttribute.DebuggingModes)", 1); diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs index 94bc94795..a2b21e944 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs @@ -29,8 +29,7 @@ public void MultipleMscorlibReferencesFound() { var metadataReader = peFile.GetMetadataReader(); - var assemblyInfo = objectFinder.GetSystemRuntimeAssemblyInformation(metadataReader); - + Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); Assert.Equal("mscorlib", assemblyInfo.Name); Assert.Equal("4.0.0.0", assemblyInfo.Version.ToString()); Assert.Equal("neutral", assemblyInfo.Culture); @@ -53,8 +52,7 @@ public void NetstandardReferencesOnly() { var metadataReader = peFile.GetMetadataReader(); - var assemblyInfo = objectFinder.GetSystemRuntimeAssemblyInformation(metadataReader); - + Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); Assert.Equal("netstandard", assemblyInfo.Name); Assert.Equal("2.0.0.0", assemblyInfo.Version.ToString()); Assert.Equal("neutral", assemblyInfo.Culture); @@ -79,16 +77,33 @@ public void ResourceAssembliesGetSkipped() { var metadataReader = peFile.GetMetadataReader(); - var ex = Record.Exception(() => - { - var assemblyInfo = objectFinder.GetSystemRuntimeAssemblyInformation(metadataReader); + Assert.False(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); + Assert.Null(assemblyInfo); + } + } + + [InlineData("mscorlib")] + [InlineData("netstandard")] + [InlineData("System.Private.CoreLib")] + [InlineData("System.Runtime")] + [Theory] + public void LookInFilePassedInAssembly(string name) + { + var Source = @" +.assembly " + name + @" +{ + .ver 1:0:0:0 +} "; + var objectFinder = new SystemObjectFinder(new DotNetFrameworkFilter()); + var file = TestAssembly.CreateFromIL(Source, name, _output); - // we shouldn't receive anything back - Assert.Null(assemblyInfo); - }); + using (var stream = file.OpenRead()) + using (var peFile = new PEReader(stream)) + { + var metadataReader = peFile.GetMetadataReader(); - // this should not throw - Assert.Null(ex); + Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); + Assert.Equal(name, assemblyInfo.Name); } } } diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs index 5ab194a30..73149a9b2 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs @@ -10,6 +10,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Text; using Xunit; using Xunit.Abstractions; @@ -19,6 +20,11 @@ internal static class TestAssembly { private static readonly Assembly s_assembly = typeof(TestAssembly).GetTypeInfo().Assembly; + public static IAssemblyFile CreateFromIL(string il, string name, ITestOutputHelper output) + { + return new ILStreamAssemblyFile(new StringAssemblyFile(name, il), output); + } + public static IAssemblyFile Create(string source, ITestOutputHelper output, bool allowUnsafe = false, IEnumerable additionalReferences = null) { switch (Path.GetExtension(source).ToLowerInvariant()) @@ -29,12 +35,31 @@ public static IAssemblyFile Create(string source, ITestOutputHelper output, bool case ".cs": return new CSharpCompileAssemblyFile(source, allowUnsafe, additionalReferences, output); case ".il": - return new ILStreamAssemblyFile(source, output); + return new ILStreamAssemblyFile(new ResourceStreamAssemblyFile(source, output), output); default: throw new ArgumentOutOfRangeException(nameof(source), source, "Unknown extension"); } } + private class StringAssemblyFile : IAssemblyFile + { + private readonly byte[] _contents; + + public StringAssemblyFile(string name, string contents) + { + Name = name; + _contents = Encoding.UTF8.GetBytes(contents); + } + + public string Name { get; } + + public string Version => string.Empty; + + public bool Exists => true; + + public Stream OpenRead() => new MemoryStream(_contents); + } + private class CSharpCompileAssemblyFile : ResourceStreamAssemblyFile { private static readonly IEnumerable s_references = new[] { typeof(object).GetTypeInfo().Assembly.Location, typeof(Uri).GetTypeInfo().Assembly.Location, typeof(Console).GetTypeInfo().Assembly.Location } @@ -129,16 +154,26 @@ public virtual Stream OpenRead() } } - private class ILStreamAssemblyFile : ResourceStreamAssemblyFile + private class ILStreamAssemblyFile : IAssemblyFile { private static readonly string s_ilAsmPath = Path.Combine(Path.GetDirectoryName(s_assembly.Location), "ilasm.exe"); - public ILStreamAssemblyFile(string fileName, ITestOutputHelper output) - : base(fileName, output) + private readonly IAssemblyFile _other; + private readonly ITestOutputHelper _output; + + public ILStreamAssemblyFile(IAssemblyFile other, ITestOutputHelper output) { + _other = other; + _output = output; } - public override Stream OpenRead() + public string Name => _other.Name; + + public string Version => _other.Version; + + public bool Exists => _other.Exists; + + public Stream OpenRead() { if (!File.Exists(s_ilAsmPath)) { @@ -148,7 +183,7 @@ public override Stream OpenRead() var ilPath = Path.GetTempFileName(); using (var fs = File.OpenWrite(ilPath)) - using (var stream = base.OpenRead()) + using (var stream = _other.OpenRead()) { stream.CopyTo(fs); } @@ -169,11 +204,11 @@ public override Stream OpenRead() var stdout = process.StandardOutput.ReadToEnd(); var stderr = process.StandardError.ReadToEnd(); - Output.WriteLine("ilasm stdout:"); - Output.WriteLine(stdout); + _output.WriteLine("ilasm stdout:"); + _output.WriteLine(stdout); - Output.WriteLine("ilasm stderr:"); - Output.WriteLine(stderr); + _output.WriteLine("ilasm stderr:"); + _output.WriteLine(stderr); Assert.Equal(0, process.ExitCode); } From f8d09474f288d9dd2b4df61b576529b30ea09e68 Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Wed, 19 Sep 2018 18:16:51 -0700 Subject: [PATCH 07/17] More style-cop rule fixes. Part 2 (#706) * Fixing SA1649: File names must match class * Adding back the suppression of most StyleCop rules except for SA1516 and SA1649 * Unsuppressing rules: SA1000 - SA1028 * Fixing SA1000 - SA1028 warnings * Unsuppressing SA1102 - SA1115 * Fixing warnings for SA1102 - SA1115 * Unsuppressing SA1100 --- rules.ruleset | 44 ------------------- .../Contracts/IVSThreadingService.cs | 2 +- .../IVsHierarchyExtensions.cs | 3 +- .../SourceMapping/CciMetadataTraverser.cs | 2 +- .../SourceMapping/CodeDocumentNavigator.cs | 34 +++++++------- .../VisualStudioProxyProvider.cs | 4 +- .../AssemblyRedirectResolver.cs | 4 +- src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs | 2 +- src/ApiPort/ApiPort/Program.cs | 6 ++- src/ApiPort/ApiPort/Proxy/ProxyProvider.cs | 3 +- src/ApiPort/ApiPort/Proxy/WebProxy.cs | 2 +- .../Analyzer/DependencyFinderEngine.cs | 16 ++++--- .../DocIdExtensions.cs | 18 +++----- .../TypeExtensions.cs | 12 ++--- .../MemberMetadataInfo.cs | 16 +++---- .../MemberMetadataInfoTypeProvider.cs | 2 +- .../MetadataReaderExtensions.cs | 7 +-- .../MethodSignatureExtensions.cs | 2 +- .../ReflectionMetadataDependencyInfo.cs | 4 +- .../Microsoft.Fx.Portability.Offline/Data.cs | 2 +- .../OfflineApiPortService.cs | 2 +- .../ExcelOpenXmlOutputWriter.cs | 6 +-- .../Analysis/AnalysisEngine.cs | 23 +++++----- .../Analysis/TargetNameParser.cs | 8 ++-- .../Analyzer/DotNetFrameworkFilter.cs | 2 +- .../Microsoft.Fx.Portability/ApiPortClient.cs | 3 +- .../ApiPortService.cs | 7 +-- .../BreakingChangeDependency.cs | 2 +- .../BreakingChangeParser.cs | 13 +++--- .../CompressedHttpClient.cs | 7 ++- .../InvalidApiPortOptionsException.cs | 2 +- .../ObjectModel/CloudApiCatalogLookup.cs | 27 ++++-------- .../Proxy/CredentialRequestType.cs | 2 +- .../Reporting/ReportGenerator.cs | 3 +- .../ServiceHeaders.cs | 2 +- .../ApiPortVS.Tests/ProjectBuilderTests.cs | 2 +- .../ManagedMetadataReaderTests.cs | 2 +- .../ManagedMetadataReaderTests.cs | 2 +- .../SystemObjectFinderTests.cs | 2 +- .../OffLineApiPortServiceTests.cs | 13 +++--- .../AnalysisEngineNuGetPackageInfoTests.cs | 37 +++++++++++++--- .../Analysis/AnalysisEngineTests.cs | 31 +++++++------ .../ApiPortServiceTests.cs | 2 +- .../AncestorApiRecommendationsTests.cs | 4 +- .../ObjectModel/IgnoreAssemblyInfoTests.cs | 22 +++++----- .../TargetMapTests.cs | 2 +- 46 files changed, 190 insertions(+), 223 deletions(-) diff --git a/rules.ruleset b/rules.ruleset index e0d798f99..6e60c71e4 100644 --- a/rules.ruleset +++ b/rules.ruleset @@ -47,51 +47,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/Contracts/IVSThreadingService.cs b/src/ApiPort/ApiPort.VisualStudio.Common/Contracts/IVSThreadingService.cs index 7c9fc4ed8..88fcba0f6 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/Contracts/IVSThreadingService.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/Contracts/IVSThreadingService.cs @@ -9,7 +9,7 @@ namespace ApiPortVS.Contracts /// /// Provides threading services to safely communicate between synchronous /// and asynchronous tasks without freezing the UI. - /// + /// /// Further reading: /// https://github.com/Microsoft/VSProjectSystem/blob/master/doc/overview/threading_model.md /// https://blogs.msdn.microsoft.com/andrewarnottms/2014/05/07/asynchronous-and-multithreaded-programming-within-vs-using-the-joinabletaskfactory/ diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/IVsHierarchyExtensions.cs b/src/ApiPort/ApiPort.VisualStudio.Common/IVsHierarchyExtensions.cs index 74fdbab17..dc8a34a1e 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/IVsHierarchyExtensions.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/IVsHierarchyExtensions.cs @@ -12,7 +12,8 @@ public static class IVsHierarchyExtensions { public static bool IsDotNetProject(this Project project) { - if (project.CodeModel == null) // e.g. F# projects + // e.g. F# projects + if (project.CodeModel == null) { return IsFSharpProject(project); } diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciMetadataTraverser.cs b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciMetadataTraverser.cs index ea165d63d..5687c58ee 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciMetadataTraverser.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciMetadataTraverser.cs @@ -46,7 +46,7 @@ from member in type.MissingMembers } // TODO: Add support for fields, properties, type definitions and attributes as well - // + // // Example: // [Serializable] // public class Foo {} diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs index bbebb8e0f..4f563a54f 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs @@ -15,8 +15,7 @@ internal static class CodeDocumentNavigator public static void Navigate(object sender, EventArgs e) { - var task = sender as Task; - if (task != null) + if (sender is Task task) { OpenDocumentTo(task.Document, task.Line, task.Column); } @@ -24,8 +23,7 @@ public static void Navigate(object sender, EventArgs e) public static void OpenDocumentTo(string documentPath, int line, int column) { - var openDocument = Package.GetGlobalService(typeof(IVsUIShellOpenDocument)) as IVsUIShellOpenDocument; - if (openDocument == null) + if (!(Package.GetGlobalService(typeof(IVsUIShellOpenDocument)) is IVsUIShellOpenDocument openDocument)) { return; } @@ -36,17 +34,15 @@ public static void OpenDocumentTo(string documentPath, int line, int column) return; } - object pvar; - window.GetProperty((int)__VSFPROPID.VSFPROPID_DocData, out pvar); + window.GetProperty((int)__VSFPROPID.VSFPROPID_DocData, out var pvar); - var buffer = pvar as VsTextBuffer; - if (buffer == null) + if (!(pvar is VsTextBuffer buffer)) { buffer = GetBufferFromProvider(pvar); } - var textManager = Package.GetGlobalService(typeof(VsTextManagerClass)) as IVsTextManager; - if (textManager != null && buffer != null) + if (Package.GetGlobalService(typeof(VsTextManagerClass)) is IVsTextManager textManager + && buffer != null) { textManager.NavigateToLineAndColumn(buffer, ref s_logicalViewGuid, line, column, line, column); } @@ -57,13 +53,15 @@ private static IVsWindowFrame GetFrameForDocument(string documentPath) var openDocument = Package.GetGlobalService(typeof(IVsUIShellOpenDocument)) as IVsUIShellOpenDocument; IVsWindowFrame window = null; - Microsoft.VisualStudio.OLE.Interop.IServiceProvider serviceProvider; - IVsUIHierarchy hierarchy; - uint itemId; try { - ErrorHandler.ThrowOnFailure(openDocument.OpenDocumentViaProject - (documentPath, ref s_logicalViewGuid, out serviceProvider, out hierarchy, out itemId, out window)); + ErrorHandler.ThrowOnFailure(openDocument.OpenDocumentViaProject( + documentPath, + ref s_logicalViewGuid, + out var serviceProvider, + out var hierarchy, + out var itemId, + out window)); } catch { @@ -75,14 +73,12 @@ private static IVsWindowFrame GetFrameForDocument(string documentPath) private static VsTextBuffer GetBufferFromProvider(object pvar) { - var bufferProvider = pvar as IVsTextBufferProvider; - if (bufferProvider == null) + if (!(pvar is IVsTextBufferProvider bufferProvider)) { return null; } - IVsTextLines lines; - bufferProvider.GetTextBuffer(out lines); + bufferProvider.GetTextBuffer(out var lines); return lines as VsTextBuffer; } } diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/VisualStudioProxyProvider.cs b/src/ApiPort/ApiPort.VisualStudio.Common/VisualStudioProxyProvider.cs index accf1a8c1..62c475f71 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/VisualStudioProxyProvider.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/VisualStudioProxyProvider.cs @@ -26,8 +26,8 @@ public VisualStudioProxyProvider(IVsWebProxy vsWebProxy) public async Task TryUpdateCredentialsAsync(Uri uri, IWebProxy proxy, CredentialRequestType type, CancellationToken cancellationToken) { - // This value will cause the web proxy service to first attempt to retrieve - // credentials from its cache and fall back to prompting if necessary. + // This value will cause the web proxy service to first attempt to retrieve + // credentials from its cache and fall back to prompting if necessary. const __VsWebProxyState oldState = __VsWebProxyState.VsWebProxyState_DefaultCredentials; // This must be run on the UI thread in case a prompt has to be shown to retrieve the credentials diff --git a/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs b/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs index 77b3700bd..23670397d 100644 --- a/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs +++ b/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs @@ -14,8 +14,8 @@ namespace ApiPortVS { /// /// Because the VSIX runs inside devenv.exe, the only configuration file that is used for redirects is - /// devenv.exe.config.We don't want to modify this machine wide configuration so we are manually setting - /// the redirects. + /// devenv.exe.config.We don't want to modify this machine wide configuration so we are manually setting + /// the redirects. /// More info: http://stackoverflow.com/a/31248093/4220757 /// internal class AssemblyRedirectResolver diff --git a/src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs b/src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs index 33c526b81..89064bbe9 100644 --- a/src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs +++ b/src/ApiPort/ApiPort.VisualStudio/PkgCmdID.cs @@ -17,5 +17,5 @@ internal static class PkgCmdID public const uint CmdIdProjectContextOptionsMenuItem = 0x0202; public const uint CmdIdSolutionContextMenuItem = 0x0300; public const uint CmdIdSolutionContextOptionsMenuItem = 0x0301; - }; + } } diff --git a/src/ApiPort/ApiPort/Program.cs b/src/ApiPort/ApiPort/Program.cs index 941a10b6e..640104ac5 100644 --- a/src/ApiPort/ApiPort/Program.cs +++ b/src/ApiPort/ApiPort/Program.cs @@ -142,7 +142,8 @@ private static PortabilityAnalyzerException GetPortabilityException(Exception e) private static IEnumerable GetRecursiveInnerExceptions(Exception ex) { - if (ex is AggregateException) // AggregateExceptions can have multiple inner exceptions + // AggregateExceptions can have multiple inner exceptions + if (ex is AggregateException) { foreach (var innerEx in (ex as AggregateException).InnerExceptions) { @@ -153,7 +154,8 @@ private static IEnumerable GetRecursiveInnerExceptions(Exception ex) } } } - else // Other exceptions can have only one inner exception + // Other exceptions can have only one inner exception + else { if (ex.InnerException != null) { diff --git a/src/ApiPort/ApiPort/Proxy/ProxyProvider.cs b/src/ApiPort/ApiPort/Proxy/ProxyProvider.cs index f5dc21b21..d612fe37b 100644 --- a/src/ApiPort/ApiPort/Proxy/ProxyProvider.cs +++ b/src/ApiPort/ApiPort/Proxy/ProxyProvider.cs @@ -149,8 +149,7 @@ private static IWebProxy GetWebProxyFromEnvironment() { webProxy.Credentials = new NetworkCredential( userName: credentials[0], - password: credentials[1] - ); + password: credentials[1]); } } diff --git a/src/ApiPort/ApiPort/Proxy/WebProxy.cs b/src/ApiPort/ApiPort/Proxy/WebProxy.cs index 5e5acda0f..d4276251c 100644 --- a/src/ApiPort/ApiPort/Proxy/WebProxy.cs +++ b/src/ApiPort/ApiPort/Proxy/WebProxy.cs @@ -86,7 +86,7 @@ string Replace(string content, string oldValue, string newValue) #else return content.Replace(oldValue, newValue); #endif - }; + } return Replace( Replace(Regex.Escape(pattern), @"\*", ".*?"), diff --git a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs index eabd51950..173807ca5 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs @@ -63,8 +63,10 @@ private void FindDependencies(IProgressTask progressTask) MemberInfo m = new MemberInfo() { MemberDocId = dep.MemberDocId, TypeDocId = dep.TypeDocId, DefinedInAssemblyIdentity = dep.DefinedInAssemblyIdentity }; // Add this memberinfo - HashSet newassembly = new HashSet(); - newassembly.Add(dep.CallingAssembly); + var newassembly = new HashSet + { + dep.CallingAssembly + }; ICollection assemblies = dependencies.AddOrUpdate(m, newassembly, (key, existingSet) => { lock (existingSet) @@ -95,8 +97,10 @@ private IEnumerable GetDependencies(string assemblyLocation) } catch { } - HashSet newValue = new HashSet(); - newValue.Add(callingAssembly); + HashSet newValue = new HashSet + { + callingAssembly + }; _unresolvedAssemblies.AddOrUpdate(e.Unresolved.Format(), newValue, (key, existingHashSet) => { lock (existingHashSet) @@ -146,7 +150,7 @@ private IEnumerable GetDependencies(string assemblyLocation) DefinedInAssemblyIdentity = definedIn }; - //return the member + // return the member yield return new MemberDependency() { CallingAssembly = assemblyInfo, @@ -160,7 +164,7 @@ private IEnumerable GetDependencies(string assemblyLocation) foreach (var refence in cciAssembly.GetTypeReferences()) { string definedIn = refence.GetAssemblyReference().ContainingAssembly.AssemblyIdentity.Format(); - //return the type + // return the type yield return new MemberDependency() { CallingAssembly = assemblyInfo, diff --git a/src/lib/Microsoft.Fx.Portability.Cci/DocIdExtensions.cs b/src/lib/Microsoft.Fx.Portability.Cci/DocIdExtensions.cs index f812bc648..4aa92191f 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/DocIdExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/DocIdExtensions.cs @@ -25,8 +25,8 @@ public static string DocId(this ITypeReference type) public static string DocId(this ITypeMemberReference member) { - //Do we need to unwrap members? - //member = member.UnWrapMember(); + // Do we need to unwrap members? + // member = member.UnWrapMember(); return MemberHelper.GetMemberSignature(member, NameFormattingOptions.DocumentationId); } @@ -52,7 +52,7 @@ public static string DocId(this AssemblyIdentity assembly) public static string DocId(this IPlatformInvokeInformation platformInvoke) { - //return string.Format("I:{0}.{1}", platformInvoke.ImportModule.Name.Value, platformInvoke.ImportName.Value); + // return string.Format("I:{0}.{1}", platformInvoke.ImportModule.Name.Value, platformInvoke.ImportName.Value); // For now so we can use this to match up with the modern sdk names only include the pinvoke name in the identifier. return string.Format(CultureInfo.InvariantCulture, "{0}", platformInvoke.ImportName.Value); @@ -62,20 +62,16 @@ public static string RefDocId(this IReference reference) { Contract.Requires(reference != null); - ITypeReference type = reference as ITypeReference; - if (type != null) + if (reference is ITypeReference type) return type.DocId(); - ITypeMemberReference member = reference as ITypeMemberReference; - if (member != null) + if (reference is ITypeMemberReference member) return member.DocId(); - IUnitNamespaceReference ns = reference as IUnitNamespaceReference; - if (ns != null) + if (reference is IUnitNamespaceReference ns) return ns.DocId(); - IAssemblyReference assembly = reference as IAssemblyReference; - if (assembly != null) + if (reference is IAssemblyReference assembly) return assembly.DocId(); Contract.Assert(false, string.Format(CultureInfo.CurrentUICulture, LocalizedStrings.FellThroughCasesIn, "DocIdExtensions.RefDocId()", reference.GetType())); diff --git a/src/lib/Microsoft.Fx.Portability.Cci/TypeExtensions.cs b/src/lib/Microsoft.Fx.Portability.Cci/TypeExtensions.cs index e4953d8c7..dde8fbb72 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/TypeExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/TypeExtensions.cs @@ -129,14 +129,12 @@ public static IAssembly GetAssembly(this ITypeDefinition type) { IUnit unit = TypeHelper.GetDefiningUnit(type); - IAssembly assembly = unit as IAssembly; - if (assembly != null) + if (unit is IAssembly assembly) { return assembly; } - IModule module = unit as IModule; - if (module != null) + if (unit is IModule module) { return module.ContainingAssembly; } @@ -148,14 +146,12 @@ public static IAssemblyReference GetAssemblyReference(this ITypeReference type) { IUnitReference unit = TypeHelper.GetDefiningUnitReference(type); - IAssemblyReference assembly = unit as IAssemblyReference; - if (assembly != null) + if (unit is IAssemblyReference assembly) { return assembly; } - IModuleReference module = unit as IModuleReference; - if (module != null) + if (unit is IModuleReference module) { return module.ContainingAssembly; } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs index c932b3cf4..5c99d8d56 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs @@ -148,15 +148,15 @@ private string GenerateTypeDocId() } /// - /// Add the type arguments for generic instances. Go through all type names, and if it is generic, such + /// Add the type arguments for generic instances. Go through all type names, and if it is generic, such /// as Hashtable`1, remove the `1. Look in the arguments list and put the list of arguments in between {} /// - /// Example: Hashtable{`0}.KeyValuePair - /// + /// Example: Hashtable{`0}.KeyValuePair + /// /// There are some interesting corner cases involving nested types - /// First, generic argument indexes are counted over all types in the nested type hierarchy. /// Therefore, OuterClass`2.InnerClass`2 should resolve as OuterClass{`0,`1}.InnerClass{`2,`3}. - /// + /// /// Secondly, it is not required that all generic arguments be made concrete. /// For example, it's possible in IL to define nested generic types OuterClass`2.InnerClass`2 and /// then pass only two generic types in GenericTypeArgs. In such cases, the type should resolve @@ -223,7 +223,7 @@ private IEnumerable GetGenericDisplayNames(IList displayNames) sb.Append(string.Join(",", GenericTypeArgs.GetRange(index, numGenericArgs))); sb.Append("}"); - // Add any part that was after the generic entry + // Add any part that was after the generic entry if (displayName.Length > offsetStringAfterGenericMarker) { var length = displayName.Length - offsetStringAfterGenericMarker; @@ -282,7 +282,7 @@ private string GenerateMemberDocId() } } - // Add the method signature + // Add the method signature if (Kind == MemberKind.Method && MethodSignature.ParameterTypes.Count() > 0) { sb.Append("("); @@ -305,8 +305,8 @@ private string GenerateMemberDocId() sb.Append("(__arglist)"); } - // Technically, we want to verify that these are marked as a special name along with the names op_Implicit or op_Explicit. However, - // since we are just using member references, we don't have enought information to know if it is. For now, we will assume that it is + // Technically, we want to verify that these are marked as a special name along with the names op_Implicit or op_Explicit. However, + // since we are just using member references, we don't have enought information to know if it is. For now, we will assume that it is // a special name if it only has one input parameter if (Kind == MemberKind.Method && MethodSignature.ParameterTypes.Length == 1 && (string.Equals(Name, "op_Implicit", StringComparison.Ordinal) || string.Equals(Name, "op_Explicit", StringComparison.Ordinal))) diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs index a718bf776..82cfe5e9b 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs @@ -167,7 +167,7 @@ public MemberMetadataInfo GetFullName(TypeReference reference, TypeReference? ch return new MemberMetadataInfo(name, info2); default: - // These cases are rare. According to spec, nil means look + // These cases are rare. According to spec, nil means look // in ExportedTypes, and Handle.ModuleDefinition means // "reference" to type defined in the current module. The // syntax generated here may be wrong. In the module definition diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs index edb72747e..cfb58f870 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs @@ -102,7 +102,7 @@ private static AssemblyReferenceInformation FormatAssemblyInfo(this MetadataRead /// /// Convert a blob referencing a public key token from a PE file into a human-readable string. - /// + /// /// If there are no bytes, the return will be 'null' /// If the length is greater than 8, it is a strong name signed assembly /// Otherwise, the key is the byte sequence @@ -120,9 +120,10 @@ private static string FormatPublicKeyToken(this MetadataReader metadataReader, B return "null"; } - if (bytes.Length > 8) // Strong named assembly + // Strong named assembly + if (bytes.Length > 8) { - // Get the public key token, which is the last 8 bytes of the SHA-1 hash of the public key + // Get the public key token, which is the last 8 bytes of the SHA-1 hash of the public key using (var sha1 = SHA1.Create()) { var token = sha1.ComputeHash(bytes); diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MethodSignatureExtensions.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MethodSignatureExtensions.cs index 21dbd3c69..7af0d60bb 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MethodSignatureExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MethodSignatureExtensions.cs @@ -11,7 +11,7 @@ namespace Microsoft.Fx.Portability internal static class MethodSignatureExtensions { /// - /// Marks all types in a method signature as enclosed. This does not change any of the inputs; instead it will create a new + /// Marks all types in a method signature as enclosed. This does not change any of the inputs; instead it will create a new /// method signature from new parameters and return type /// /// diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs index 220956c62..802803263 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs @@ -146,8 +146,8 @@ private IEnumerable GetDependencies(IAssemblyFile file) } /// - /// Add all assemblies that were referenced to the referenced assembly dictionary. By default, - /// we add every referenced assembly and will remove the ones that are actually referenced when + /// Add all assemblies that were referenced to the referenced assembly dictionary. By default, + /// we add every referenced assembly and will remove the ones that are actually referenced when /// all submitted assemblies are processed. /// /// diff --git a/src/lib/Microsoft.Fx.Portability.Offline/Data.cs b/src/lib/Microsoft.Fx.Portability.Offline/Data.cs index 502e6c39e..cda44d39a 100644 --- a/src/lib/Microsoft.Fx.Portability.Offline/Data.cs +++ b/src/lib/Microsoft.Fx.Portability.Offline/Data.cs @@ -53,7 +53,7 @@ public static IEnumerable LoadBreakingChanges() if (fileBreakingChanges == null) { - //Trace.WriteLine("No data was found in '" + file + "'"); + // Trace.WriteLine("No data was found in '" + file + "'"); } else { diff --git a/src/lib/Microsoft.Fx.Portability.Offline/OfflineApiPortService.cs b/src/lib/Microsoft.Fx.Portability.Offline/OfflineApiPortService.cs index 2afcad90f..7edc96d71 100644 --- a/src/lib/Microsoft.Fx.Portability.Offline/OfflineApiPortService.cs +++ b/src/lib/Microsoft.Fx.Portability.Offline/OfflineApiPortService.cs @@ -59,7 +59,7 @@ public async Task>> SendA { var response = _requestAnalyzer.AnalyzeRequest(a, Guid.NewGuid().ToString()); - if(!formats?.Any() ?? true) + if (!formats?.Any() ?? true) { var defaultFormat = await GetDefaultResultFormatAsync(); formats = new[] { defaultFormat.Response.DisplayName }; diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs index 7779a11d7..67455336c 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs @@ -347,7 +347,7 @@ private void GenerateBreakingChangesPage(Worksheet worksheet, IEnumerable FindBreakingChangeSkippedAssemblies(IEnumerable { foreach (AssemblyInfo a in userAssemblies) { + // The assembly must be in assembliesToIgnore and + // either be 'IgnoreForAllTargets' or + // all targeted Frameworks are in the ignore list for the assembly if (assembliesToIgnore.Any(i => - i.AssemblyIdentity.Equals(a.AssemblyIdentity, StringComparison.OrdinalIgnoreCase) && // The assembly must be in assembliesToIgnore and - (i.IgnoreForAllTargets || // either be 'IgnoreForAllTargets' or - targets.All(f => i.TargetsIgnored.Contains(f.FullName, StringComparer.OrdinalIgnoreCase))) // all targeted Frameworks are in the ignore list for the assembly - )) + i.AssemblyIdentity.Equals(a.AssemblyIdentity, StringComparison.OrdinalIgnoreCase) && + (i.IgnoreForAllTargets || + targets.All(f => i.TargetsIgnored.Contains(f.FullName, StringComparer.OrdinalIgnoreCase))))) { yield return a; } @@ -118,8 +120,8 @@ private static bool BreakingChangeIsInVersionRange(IEnumerable targetVe public IList FindMembersNotInTargets(IEnumerable targets, ICollection submittedAssemblies, IDictionary> dependencies) { - //Trace.TraceInformation("Computing members not in target"); - Stopwatch sw = new Stopwatch(); + // Trace.TraceInformation("Computing members not in target"); + var sw = new Stopwatch(); sw.Start(); if (dependencies == null || dependencies.Keys == null || targets == null) @@ -139,7 +141,8 @@ public IList FindMembersNotInTargets(IEnumerable targ .ToList(); sw.Stop(); - //Trace.TraceInformation("Computing members not in target took '{0}'", sw.Elapsed); + + // Trace.TraceInformation("Computing members not in target took '{0}'", sw.Elapsed); return missingMembers; } @@ -183,9 +186,7 @@ private static bool IsSupportedAcrossTargets(IApiCatalogLookup catalog, string m // For each target we should get the status of the api: // - 'null' if not supported // - Version introduced in - Version status; - - if (!IsSupportedOnTarget(catalog, memberDocId, target, out status)) + if (!IsSupportedOnTarget(catalog, memberDocId, target, out var status)) { isSupported = false; } @@ -234,7 +235,7 @@ public IEnumerable GetNuGetPackagesInfoFromAssembly(IEnumerabl { foreach (var nuGetPackageInfo in packages) { - //check if the assembly is set + // Check if the assembly is set if (nuGetPackageInfo.AssemblyInfo == null) { yield return new NuGetPackageInfo(nuGetPackageInfo.PackageId, nuGetPackageInfo.SupportedVersions, assembly); diff --git a/src/lib/Microsoft.Fx.Portability/Analysis/TargetNameParser.cs b/src/lib/Microsoft.Fx.Portability/Analysis/TargetNameParser.cs index 2e9c6579f..a261e8c2f 100644 --- a/src/lib/Microsoft.Fx.Portability/Analysis/TargetNameParser.cs +++ b/src/lib/Microsoft.Fx.Portability/Analysis/TargetNameParser.cs @@ -25,7 +25,7 @@ public TargetNameParser(IApiCatalogLookup catalog, string defaultTargets) /// Maps the list of targets specified as strings to a list of supported target names. /// /// - /// If no targets are specified, return the list of all public targets with their latest version. + /// If no targets are specified, return the list of all public targets with their latest version. /// - From the list of public targets, filter out the ones that are NOT in the configuration setting described by 'DefaultTargets' /// Note: This allows us to support Mono targets without having them automatically show up in the default target list. /// If targets are specified, parse them like this: @@ -70,7 +70,7 @@ private IEnumerable GetDefaultTargets(string defaultTargets) // Create a hashset of all the targets specified in the configuration setting. HashSet parsedDefaultTargets = new HashSet(ParseTargets(defaultTargetsSplit, skipNonExistent: true)); - //return all the public targets (their latest versions) as long as they also show up the default targets set. + // return all the public targets (their latest versions) as long as they also show up the default targets set. return _catalog.GetPublicTargets() .Select(plat => plat.Identifier) .Distinct() @@ -79,8 +79,8 @@ private IEnumerable GetDefaultTargets(string defaultTargets) } /// - /// Parse a string containing target names into FrameworkNames. - /// + /// Parse a string containing target names into FrameworkNames. + /// /// Try the following in order: /// 1. Check if the target specified uses the 'simple' name (i.e. Windows, .NET Framework) then get the latest version for it /// 2. Try to parse it as a target name. If the target was not a valid FrameworkName, an ArgumentException will be thrown and passed down to user diff --git a/src/lib/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs b/src/lib/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs index ee3227cdb..c81434b3a 100644 --- a/src/lib/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs +++ b/src/lib/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs @@ -22,7 +22,7 @@ public class DotNetFrameworkFilter : IDependencyFilter "31bf3856ad364e35", // SILVERLIGHT "24eec0d8c86cda1e", // PHONE "0738eb9f132ed756", // MONO - "cc7b13ffcd2ddd51" // NetStandard + "cc7b13ffcd2ddd51" // NetStandard }, StringComparer.OrdinalIgnoreCase); private static readonly IEnumerable s_frameworkAssemblyNamePrefixes = new[] diff --git a/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs b/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs index d6772486c..3be4bb1a8 100644 --- a/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs +++ b/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs @@ -324,8 +324,7 @@ private ReportingResult GetReportingResult(AnalyzeRequest request, AnalyzeRespon dependencyInfo?.UnresolvedAssemblies, response.UnresolvedUserAssemblies, dependencyInfo?.AssembliesWithErrors, - response.NuGetPackages - ); + response.NuGetPackages); } catch (Exception) { diff --git a/src/lib/Microsoft.Fx.Portability/ApiPortService.cs b/src/lib/Microsoft.Fx.Portability/ApiPortService.cs index 4918a7c67..b4fffcd56 100644 --- a/src/lib/Microsoft.Fx.Portability/ApiPortService.cs +++ b/src/lib/Microsoft.Fx.Portability/ApiPortService.cs @@ -133,7 +133,8 @@ public void Dispose() private async Task> GetResultFormatsAsync(IEnumerable formats) { - if (!formats?.Any() ?? true) //no "resultFormat" string option provider by user + // No "resultFormat" string option provider by user + if (!formats?.Any() ?? true) { var defaultFormat = await GetDefaultResultFormatAsync(); return new[] { defaultFormat.Response }; @@ -164,9 +165,9 @@ private static HttpMessageHandler BuildMessageHandler(string endpoint, IProxyPro throw new ArgumentOutOfRangeException(nameof(endpoint), endpoint, LocalizedStrings.MustBeValidEndpoint); } - // Create the URI directly from a string (rather than using a hard-coded scheme or port) because + // Create the URI directly from a string (rather than using a hard-coded scheme or port) because // even though production use of ApiPort should always use HTTPS, developers using a non-production - // portability service URL (via the -e command line parameter) may need to specify a different + // portability service URL (via the -e command line parameter) may need to specify a different // scheme or port. var uri = new Uri(endpoint); diff --git a/src/lib/Microsoft.Fx.Portability/BreakingChangeDependency.cs b/src/lib/Microsoft.Fx.Portability/BreakingChangeDependency.cs index f8058456f..cc990d360 100644 --- a/src/lib/Microsoft.Fx.Portability/BreakingChangeDependency.cs +++ b/src/lib/Microsoft.Fx.Portability/BreakingChangeDependency.cs @@ -16,7 +16,7 @@ public class BreakingChangeDependency : IEquatable public bool Equals(BreakingChangeDependency other) { - return Member.Equals(other.Member) + return Member.Equals(other.Member) && (Break.CompareTo(other.Break) == 0) && DependantAssembly.Equals(other.DependantAssembly); } diff --git a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs index 65ecf8972..02a346cef 100644 --- a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs +++ b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs @@ -91,8 +91,7 @@ public static IEnumerable FromMarkdown(Stream stream, IEnumerabl } else if (splitTitle.Length == 2) { - int id; - if (int.TryParse(splitTitle[0], out id)) + if (int.TryParse(splitTitle[0], out var id)) { currentBreak.Id = id.ToString(CultureInfo.InvariantCulture); currentBreak.Title = splitTitle[1].Trim(); @@ -106,7 +105,8 @@ public static IEnumerable FromMarkdown(Stream stream, IEnumerabl // Clear state state = ParseState.None; } - else if (currentBreak != null) // Only parse breaking change if we've seen a breaking change header ("## ...") + // Only parse breaking change if we've seen a breaking change header ("## ...") + else if (currentBreak != null) { // State changes if (currentLine.StartsWith("###", StringComparison.Ordinal)) @@ -184,8 +184,8 @@ public static IEnumerable FromMarkdown(Stream stream, IEnumerabl else if (currentLine.StartsWith("[More information]", StringComparison.OrdinalIgnoreCase)) { currentBreak.Link = currentLine.Substring("[More information]".Length) - .Trim(' ', '(', ')', '[', ']', '\t', '\n', '\r') // Remove markdown link enclosures - .Replace("\\(", "(").Replace("\\)", ")"); // Unescape parens in link + .Trim(' ', '(', ')', '[', ']', '\t', '\n', '\r') // Remove markdown link enclosures + .Replace("\\(", "(").Replace("\\)", ")"); // Unescape parens in link state = ParseState.None; } @@ -325,8 +325,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState if (!allowedCategories?.Contains(currentLine, StringComparer.OrdinalIgnoreCase) ?? false) { throw new InvalidOperationException( - string.Format(CultureInfo.CurrentCulture, LocalizedStrings.InvalidCategoryDetected, currentLine) - ); + string.Format(CultureInfo.CurrentCulture, LocalizedStrings.InvalidCategoryDetected, currentLine)); } if (currentBreak.Categories == null) diff --git a/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs b/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs index 1ad4a3119..5eaeb92dc 100644 --- a/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs +++ b/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs @@ -32,7 +32,7 @@ internal class CompressedHttpClient : HttpClient public CompressedHttpClient(ProductInformation info) : this(info, new HttpClientHandler { #if !FEATURE_SERVICE_POINT_MANAGER - SslProtocols = SupportedSSLProtocols, + SslProtocols = SupportedSSLProtocols, #endif AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }) @@ -123,7 +123,7 @@ private async Task> CallInternalAsync(Http DisplayName = "Json", MimeType = "application/json", FileExtension = ".json" - }; ; + }; var response = await CallInternalAsync(request, new[] { json }); var result = response.Response.Single().Data.Deserialize(); @@ -183,8 +183,7 @@ private async Task>> Call break; } - StringValues contentTypes; - section.Headers.TryGetValue("Content-Type", out contentTypes); + section.Headers.TryGetValue("Content-Type", out var contentTypes); if (contentTypes.Count == 0) { diff --git a/src/lib/Microsoft.Fx.Portability/InvalidApiPortOptionsException.cs b/src/lib/Microsoft.Fx.Portability/InvalidApiPortOptionsException.cs index 7e1633099..f20728be5 100644 --- a/src/lib/Microsoft.Fx.Portability/InvalidApiPortOptionsException.cs +++ b/src/lib/Microsoft.Fx.Portability/InvalidApiPortOptionsException.cs @@ -8,7 +8,7 @@ namespace Microsoft.Fx.Portability /// public class InvalidApiPortOptionsException : PortabilityAnalyzerException { - public InvalidApiPortOptionsException(string message) + public InvalidApiPortOptionsException(string message) : base(message) { } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/CloudApiCatalogLookup.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/CloudApiCatalogLookup.cs index b86516ffa..daf5e5ac9 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/CloudApiCatalogLookup.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/CloudApiCatalogLookup.cs @@ -73,13 +73,11 @@ public virtual IEnumerable DocIds /// /// Gets the ApiDefinition for a docId. /// - /// The corresponding ApiDefinition if it exists. + /// The corresponding ApiDefinition if it exists. /// If docId is null/empty or does not exist, returns null. public virtual ApiDefinition GetApiDefinition(string docId) { - ApiDefinition apiDefinition; - - if (string.IsNullOrEmpty(docId) || !_docIdToApi.TryGetValue(docId, out apiDefinition)) + if (string.IsNullOrEmpty(docId) || !_docIdToApi.TryGetValue(docId, out var apiDefinition)) { return null; } @@ -96,14 +94,13 @@ public virtual bool IsFrameworkMember(string docId) public virtual bool IsMemberInTarget(string docId, FrameworkName targetName, out Version introducedVersion) { - Dictionary targets; introducedVersion = null; // The docId is a member in the target if: // - There is an entry for the API. // - The entry for the API contains the target. // - The version for when the API was introduced is before (or equal) to the target version. - if (!_apiMapping.TryGetValue(docId, out targets)) + if (!_apiMapping.TryGetValue(docId, out var targets)) return false; if (!targets.TryGetValue(targetName.Identifier, out introducedVersion)) @@ -114,16 +111,14 @@ public virtual bool IsMemberInTarget(string docId, FrameworkName targetName, out public virtual bool IsMemberInTarget(string docId, FrameworkName targetName) { - Version version; - return IsMemberInTarget(docId, targetName, out version); + return IsMemberInTarget(docId, targetName, out var version); } public virtual string GetApiMetadata(string docId, string metadataKey) { - Dictionary metadata; string metadataValue = null; - if (_apiMetadata.TryGetValue(docId, out metadata)) + if (_apiMetadata.TryGetValue(docId, out var metadata)) { metadata.TryGetValue(metadataKey, out metadataValue); } @@ -147,12 +142,9 @@ public virtual bool IsFrameworkAssembly(string assemblyIdentity) public virtual Version GetVersionIntroducedIn(string docId, FrameworkName target) { - Dictionary targets; - Version versionIntroducedIn; - - if (_apiMapping.TryGetValue(docId, out targets)) + if (_apiMapping.TryGetValue(docId, out var targets)) { - if (targets.TryGetValue(target.Identifier, out versionIntroducedIn)) + if (targets.TryGetValue(target.Identifier, out var versionIntroducedIn)) { return versionIntroducedIn; } @@ -163,8 +155,7 @@ public virtual Version GetVersionIntroducedIn(string docId, FrameworkName target public virtual FrameworkName GetLatestVersion(string targetIdentifier) { - FrameworkName name; - if (_latestTargetVersion.TryGetValue(targetIdentifier, out name)) + if (_latestTargetVersion.TryGetValue(targetIdentifier, out var name)) { return name; } @@ -182,7 +173,7 @@ public virtual IEnumerable GetAllTargets() } /// - /// Retrieves the ancestors for a given docId. + /// Retrieves the ancestors for a given docId. /// This retrieves the Api's parent first and then the parent's ancestor /// until it reaches the root. /// If the docId does not exist or is null, it will return an empty diff --git a/src/lib/Microsoft.Fx.Portability/Proxy/CredentialRequestType.cs b/src/lib/Microsoft.Fx.Portability/Proxy/CredentialRequestType.cs index a69c1b20e..341d50b64 100644 --- a/src/lib/Microsoft.Fx.Portability/Proxy/CredentialRequestType.cs +++ b/src/lib/Microsoft.Fx.Portability/Proxy/CredentialRequestType.cs @@ -14,7 +14,7 @@ public enum CredentialRequestType Proxy, /// - /// Indicates that the remote server rejected the previous request as unauthorized. This + /// Indicates that the remote server rejected the previous request as unauthorized. This /// suggests that the server does not know who the caller is (i.e. the caller is not /// authenticated). /// diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ReportGenerator.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ReportGenerator.cs index a206e62a0..624260f7d 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ReportGenerator.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ReportGenerator.cs @@ -128,13 +128,12 @@ private static List ComputePerAssemblyUsage( /// /// Give a list of assemblies it will compute which name an assembly must have. - /// For instance, if we have a single assembly, we will use the assembly simple name. + /// For instance, if we have a single assembly, we will use the assembly simple name. /// If we have more than one then we should use the full assembly name in order to distinguish betweeen them /// private static Dictionary ComputeAssemblyNames(IEnumerable assemblyUsage) { // Group the assemblies by the simple name. In order to do that we need to parse the assembly identity and use the Name property. - // var mapAssemblyNameOccurences = assemblyUsage.GroupBy(asui => new System.Reflection.AssemblyName(asui.SourceAssembly.AssemblyIdentity).Name) .SelectMany(assemblyNameGroup => assemblyNameGroup.Select(assemblyInfo => new { diff --git a/src/lib/Microsoft.Fx.Portability/ServiceHeaders.cs b/src/lib/Microsoft.Fx.Portability/ServiceHeaders.cs index 6a0fa787a..04ef715fa 100644 --- a/src/lib/Microsoft.Fx.Portability/ServiceHeaders.cs +++ b/src/lib/Microsoft.Fx.Portability/ServiceHeaders.cs @@ -13,7 +13,7 @@ namespace Microsoft.Fx.Portability { public class ServiceHeaders { - // Do not change these + // Do not change these public const string EndpointHeader = "WebsiteUrl"; public const string ApiInfoHeader = "DotNetApiInfoUrl"; public const string SubmissionUrlHeader = "SubmissionUrl"; diff --git a/tests/ApiPort/ApiPortVS.Tests/ProjectBuilderTests.cs b/tests/ApiPort/ApiPortVS.Tests/ProjectBuilderTests.cs index 5242a6767..e5f73f580 100644 --- a/tests/ApiPort/ApiPortVS.Tests/ProjectBuilderTests.cs +++ b/tests/ApiPort/ApiPortVS.Tests/ProjectBuilderTests.cs @@ -29,7 +29,7 @@ public static void Build_VsFailsToStartBuild_TaskResultSetFalse() Assert.False(result); - // Checking that we are not listening to build events + // Checking that we are not listening to build events // if starting a build was not successful buildManager.DidNotReceiveWithAnyArgs() .AdviseUpdateSolutionEvents(null, out pdwCookie); diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs index 1b36a224b..c0783c553 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs @@ -39,7 +39,7 @@ private static void CompareFinders(params string[] paths) private static void CompareFinders(IEnumerable paths) { - //CompareFinders(new ManagedMetadataReaderDependencyFinder(), new CciDependencyFinder(), paths); + // CompareFinders(new ManagedMetadataReaderDependencyFinder(), new CciDependencyFinder(), paths); } private static void CompareFinders(IDependencyFinder finder1, IDependencyFinder finder2, IEnumerable paths) diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs index 513ebf682..4a17aa693 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs @@ -214,7 +214,7 @@ public void MultidimensionalPrimitiveArray() var systemObject = dependencies.Dependencies.FirstOrDefault(o => string.Equals(o.Key.MemberDocId, objectDocId, StringComparison.Ordinal)).Key; Assert.NotNull(systemObject); - //Test that the DefinedInAssemblyIdentity of the primitive array is not null/empty and it is the same as the one of System.Object + // Test that the DefinedInAssemblyIdentity of the primitive array is not null/empty and it is the same as the one of System.Object var definedInAssemblyIdentity = primitiveArray.DefinedInAssemblyIdentity; var isNullOrWhiteSpace = string.IsNullOrWhiteSpace(definedInAssemblyIdentity); diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs index a2b21e944..df6433cdb 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs @@ -38,7 +38,7 @@ public void MultipleMscorlibReferencesFound() } /// - /// Test that SystemObjectFinder works even for netstandard facade + /// Test that SystemObjectFinder works even for netstandard facade /// assemblies that may not have references to mscorlib or system.runtime /// [Fact] diff --git a/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs b/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs index 36426df8b..758770891 100644 --- a/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs @@ -27,8 +27,7 @@ public class OffLineApiPortServiceTests CreateTargetMapper(), CreateCollectionOfReportWriters(), CreateTargetNameParser(), - CreateApiRecommendations() - ); + CreateApiRecommendations()); [Fact] public async Task QueryDocIdsWithNullThrowsArgumentNullException() @@ -120,7 +119,7 @@ public async Task QueryDocIdsWithOneItemEmptyString() { var docIdsToPass = new List { - $"T:{ValidDocId}0" , + $"T:{ValidDocId}0", $"T:{ValidDocId}1", $"P:{ValidDocId}1", "", @@ -131,7 +130,7 @@ public async Task QueryDocIdsWithOneItemEmptyString() var expectedDocIds = new List { - $"T:{ValidDocId}0" , + $"T:{ValidDocId}0", $"T:{ValidDocId}1", $"P:{ValidDocId}1" }; @@ -146,7 +145,7 @@ public async Task QueryDocIdsWithDifferentDocIDCassingAreInvalid() { var expectedDocIds = new List { - $"T:{ValidDocId.ToUpper(CultureInfo.InvariantCulture)}0" , + $"T:{ValidDocId.ToUpper(CultureInfo.InvariantCulture)}0", $"M:{ValidDocId.ToUpper(CultureInfo.InvariantCulture)}1", $"P:{ValidDocId}0" }; @@ -216,13 +215,13 @@ private static IApiCatalogLookup CreateApiCatalogLookup() { var catalog = Substitute.For(); - //Add some different types of DocIds + // Add some different types of DocIds AddDocIdsForType("T", catalog); AddDocIdsForType("P", catalog); AddDocIdsForType("M", catalog); AddDocIdsForType("E", catalog); - //Add some different type of DocIds with Parameters + // Add some different type of DocIds with Parameters AddDocIdWithParameter("M", catalog); AddDocIdWithParameter("T", catalog); diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineNuGetPackageInfoTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineNuGetPackageInfoTests.cs index 63d2e62cb..105b76e6f 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineNuGetPackageInfoTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineNuGetPackageInfoTests.cs @@ -45,8 +45,8 @@ public static void TestGetNugetPackageInfo() { new NuGetPackageInfo(packageId, new Dictionary() { - {Windows80, nugetPackageWin80Version }, - { NetStandard16, nugetPackageNetStandardVersion}, + { Windows80, nugetPackageWin80Version }, + { NetStandard16, nugetPackageNetStandardVersion }, }) }; @@ -96,7 +96,7 @@ public static void ComputeAssembliesToRemove_PackageFound() var nugetPackageResult = new[] { - new NuGetPackageInfo(packageId, new Dictionary() { { Windows81, packageVersion }, { NetStandard16, packageVersion } },userNuGetPackage.AssemblyIdentity) + new NuGetPackageInfo(packageId, new Dictionary() { { Windows81, packageVersion }, { NetStandard16, packageVersion } }, userNuGetPackage.AssemblyIdentity) }; // Act @@ -130,7 +130,13 @@ public static void ComputeAssembliesToRemove_PackageNotFound() var nugetPackageResult = new[] { - new NuGetPackageInfo(packageId, new Dictionary(){{Windows81, packageVersion }, { NetStandard16, null } }, userNuGetPackage.AssemblyIdentity) + new NuGetPackageInfo(packageId, + new Dictionary() + { + { Windows81, packageVersion }, + { NetStandard16, null }, + }, + userNuGetPackage.AssemblyIdentity) }; var assemblies = engine.ComputeAssembliesToRemove(inputAssemblies, targets, nugetPackageResult); @@ -139,7 +145,12 @@ public static void ComputeAssembliesToRemove_PackageNotFound() var nugetPackageResult2 = new[] { - new NuGetPackageInfo(packageId, new Dictionary(){{Windows81, packageVersion }}, userNuGetPackage.AssemblyIdentity) + new NuGetPackageInfo(packageId, + new Dictionary() + { + { Windows81, packageVersion } + }, + userNuGetPackage.AssemblyIdentity) }; assemblies = engine.ComputeAssembliesToRemove(inputAssemblies, targets, nugetPackageResult); @@ -171,7 +182,13 @@ public static void ComputeAssembliesToRemove_AssemblyExplicitlyPassedIn() var nugetPackageResult = new[] { - new NuGetPackageInfo(packageId, new Dictionary(){{Windows81, packageVersion }, { NetStandard16, packageVersion } }, userNuGetPackage.AssemblyIdentity) + new NuGetPackageInfo(packageId, + new Dictionary() + { + { Windows81, packageVersion }, + { NetStandard16, packageVersion } + }, + userNuGetPackage.AssemblyIdentity) }; var assemblies = engine.ComputeAssembliesToRemove(inputAssemblies, targets, nugetPackageResult); @@ -199,7 +216,13 @@ public static void ComputeAssembliesToRemove_AssemblyFlagNotSet() var nugetPackageResult = new[] { - new NuGetPackageInfo(packageId, new Dictionary(){{Windows81, packageVersion }, { NetStandard16, packageVersion } }, userNuGetPackage.AssemblyIdentity) + new NuGetPackageInfo(packageId, + new Dictionary() + { + { Windows81, packageVersion }, + { NetStandard16, packageVersion } + }, + userNuGetPackage.AssemblyIdentity) }; var assemblies = engine.ComputeAssembliesToRemove(inputAssemblies, targets, nugetPackageResult); diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs index b02929853..b1fa503c6 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs @@ -361,7 +361,7 @@ public static void ShowRetargettingIssuesFalseShouldReturnOnlyRuntimeIssues() Assert.Equal(3, result.Count()); - //verify only 3, 4 and 5 are in the list + // verify only 3, 4 and 5 are in the list int expectedID = 3; foreach (BreakingChangeDependency bcd in result) { @@ -390,7 +390,7 @@ public static void ShowRetargettingIssuesTrueShouldReturnRuntimeAndRetargettingI Assert.Equal(5, result.Count()); - //verify 1, 2, 3, 4 and 5 are in the list + // verify 1, 2, 3, 4 and 5 are in the list int expectedID = 1; foreach (BreakingChangeDependency bcd in result) { @@ -542,12 +542,12 @@ private static IApiRecommendations GenerateTestRecommendationsForShowRetargettin { int lastIDUsed = 1; var recommendations = Substitute.For(); - List breakingChanges = new List(); + var breakingChanges = new List(); - //add requested number of retargetting issues + // add requested number of retargetting issues for (int i = 0; i < numOfRetargettingIssues; i++) { - //add a new breaking change + // add a new breaking change BreakingChange bc = new BreakingChange { ApplicableApis = new[] { TestDocId1 }, @@ -561,11 +561,11 @@ private static IApiRecommendations GenerateTestRecommendationsForShowRetargettin lastIDUsed++; } - //add requested number of runtime issues + // add requested number of runtime issues for (int i = 0; i < numOfRuntimeIssues; i++) { - //add a new breaking change - BreakingChange bc = new BreakingChange + // add a new breaking change + var bc = new BreakingChange { ApplicableApis = new[] { TestDocId1 }, Id = lastIDUsed.ToString(CultureInfo.CurrentCulture), @@ -588,8 +588,13 @@ private static IApiRecommendations GenerateTestRecommendationsForShowRetargettin private static ICollection GenerateIgnoreAssemblies(bool otherAssm, string[] targetFrameworks) { - return new[] { - new IgnoreAssemblyInfo() { AssemblyIdentity = otherAssm? "userAsm2, Version=2.0.0.0" : "userAsm1, Version=1.0.0.0", TargetsIgnored = targetFrameworks } + return new[] + { + new IgnoreAssemblyInfo + { + AssemblyIdentity = otherAssm ? "userAsm2, Version=2.0.0.0" : "userAsm1, Version=1.0.0.0", + TargetsIgnored = targetFrameworks + } }; } @@ -609,9 +614,9 @@ private static IDictionary> GenerateTestDa return new Dictionary> { - {mi1, new[] { userAsm1 } }, - {mi2, new[] { userAsm2 } }, - {mi3, new[] { userAsm3 } }, + { mi1, new[] { userAsm1 } }, + { mi2, new[] { userAsm2 } }, + { mi3, new[] { userAsm3 } }, }; } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs index ecaf4dc20..bc487763e 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs @@ -21,7 +21,7 @@ public ApiPortServiceTests() var httpMessageHandler = new TestHandler(HttpRequestConverter); var productInformation = new ProductInformation("ApiPort_Tests"); - //Create a fake ApiPortService which uses the TestHandler to send back the response message + // Create a fake ApiPortService which uses the TestHandler to send back the response message _apiPortService = new ApiPortService("http://localhost", httpMessageHandler, productInformation); } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/AncestorApiRecommendationsTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/AncestorApiRecommendationsTests.cs index a1b734d6f..dab7eeb6e 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/AncestorApiRecommendationsTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/AncestorApiRecommendationsTests.cs @@ -78,7 +78,7 @@ public static void GetRecommendedChange_NoAncestors() } /// - /// Verify that the first recommended change (closest to the docId is + /// Verify that the first recommended change (closest to the docId is /// returned if we have multiple matching ones). /// [Fact] @@ -176,7 +176,7 @@ public static void GetBreakingChange_NoAncestors() } /// - /// Verify that the first Breaking change (closest to the docId is + /// Verify that the first Breaking change (closest to the docId is /// returned if we have multiple matching ones). /// [Fact] diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/IgnoreAssemblyInfoTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/IgnoreAssemblyInfoTests.cs index e6b63d341..115c86416 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/IgnoreAssemblyInfoTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/IgnoreAssemblyInfoTests.cs @@ -8,25 +8,25 @@ namespace Microsoft.Fx.Portability.Tests.ObjectModel { public class IgnoreAssemblyInfoTests { - private IgnoreAssemblyInfo[] _set1 = new[] { - new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new [] {"v1", "v2"} }, - new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar", TargetsIgnored = new [] {"v2"} } + private readonly IgnoreAssemblyInfo[] _set1 = new[] { + new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new[] { "v1", "v2" } }, + new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar", TargetsIgnored = new[] { "v2" } } }; - private IgnoreAssemblyInfo[] _set2 = new[] { - new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new [] {"v1", "v3"} }, - new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar", TargetsIgnored = new [] {"v1"} }, + private readonly IgnoreAssemblyInfo[] _set2 = new[] { + new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new[] { "v1", "v3" } }, + new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar", TargetsIgnored = new[] { "v1" } }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Baz", TargetsIgnored = new string[0] } }; - private IgnoreAssemblyInfo[] _set3 = new[] { - new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new [] {"V1"} }, + private readonly IgnoreAssemblyInfo[] _set3 = new[] { + new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new[] { "V1" } }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar" }, - new IgnoreAssemblyInfo() { AssemblyIdentity = "Baz", TargetsIgnored = new [] {"v1"} } + new IgnoreAssemblyInfo() { AssemblyIdentity = "Baz", TargetsIgnored = new[] { "v1" } } }; - private IgnoreAssemblyInfo[] _combined = new[] { - new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new [] {"v1", "v2", "v3"} }, + private readonly IgnoreAssemblyInfo[] _combined = new[] { + new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new[] { "v1", "v2", "v3" } }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar" }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Baz" } }; diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs index 16b9afb39..240fcec73 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs @@ -365,7 +365,7 @@ public static void XmlGetAliasMultipleAliases() "; - var map = LoadXml(xml); ; + var map = LoadXml(xml); Assert.Equal("Alias1", map.GetAlias("TestTarget1")); } From a4506d00e683d10688b70a462e19060e2cd1ae60 Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Wed, 19 Sep 2018 18:57:51 -0700 Subject: [PATCH 08/17] More style cop rule fixes. Part 3 (#707) * Unsuppressing SA1118 - SA1123 * Fixing SA1118 - SA1123 warnings * Unsuppressing SA1125 - SA1200 * Fixing warnings SA1125 - SA1200 * Unsuppressing SA1203, SA1205 - SA1217 * Fixes SA1203, SA1205-SA1217 --- rules.ruleset | 35 ------------------- .../AssemblyFile.cs | 2 +- .../SourceMapping/CodeDocumentNavigator.cs | 2 +- .../ApiPort.VisualStudio/ApiPortVSPackage.cs | 5 +-- .../AssemblyRedirectResolver.cs | 18 +++++----- .../ApiPort.VisualStudio/ServiceProvider.cs | 4 +-- .../StatusBarProgressReporter.cs | 2 +- .../Views/AnalysisOutputToolWindow.cs | 3 +- src/ApiPort/ApiPort/ConsoleApiPort.cs | 2 +- .../ApiPort/ConsoleProgressReporter.cs | 3 +- src/ApiPort/ApiPort/Program.cs | 2 +- src/ApiPort/ApiPort/Proxy/WebProxy.cs | 2 +- .../AssemblyIdentityHelpers.cs | 2 +- .../MemberMetadataInfoTypeProvider.cs | 8 ++--- .../MetadataReaderExtensions.cs | 2 +- .../ExcelOpenXmlOutputWriter.cs | 14 ++++---- .../OpenXmlExtensions.cs | 14 +++++--- .../HtmlReportWriter.cs | 8 ++--- .../AliasMappedToMultipleNamesException.cs | 5 ++- .../ApiPortService.cs | 2 +- .../BreakingChangeParser.cs | 17 +++++---- .../MovedPermanentlyException.cs | 5 ++- .../ObjectModel/AncestorApiRecommendations.cs | 2 +- .../ObjectModel/IgnoreAssemblyInfoList.cs | 9 +++-- .../Proxy/ProxyAuthenticationHandler.cs | 2 +- .../Reporting/ObjectModel/MissingTypeInfo.cs | 6 ++-- .../RequestTooLargeException.cs | 2 +- .../Microsoft.Fx.Portability/TargetMapper.cs | 2 +- .../TargetMapperException.cs | 10 ++++-- .../UnknownTargetException.cs | 5 +-- .../Microsoft.Fx.Portability/UrlBuilder.cs | 4 +-- .../ApiPortVS.Tests/ProjectBuilderTests.cs | 17 +++------ .../ApiPortVS.Tests/TestAssemblyFile.cs | 2 +- .../CciAnalyzerTests.cs | 4 +-- .../ManagedMetadataReaderTests.cs | 8 ++--- .../TestAssembly.cs | 10 +++--- .../TestAssemblyFile.cs | 1 - .../TestAssembly.cs | 3 +- .../OffLineApiPortServiceTests.cs | 2 +- .../Analysis/AnalysisEngineTests.cs | 12 +++---- .../Analysis/TargetNameParserTests.cs | 6 ++-- .../ApiPortServiceTests.cs | 12 ++++--- .../NuGetPackageInfoComparerTests.cs | 6 ++-- .../ObjectModel/NuGetPackageInfoTests.cs | 2 +- .../ObjectModel/TargetInformationTests.cs | 9 ++--- .../SerializationTests.cs | 13 +++---- .../TargetMapTests.cs | 10 +++--- .../TestData/TestCatalog.cs | 5 ++- 48 files changed, 145 insertions(+), 176 deletions(-) diff --git a/rules.ruleset b/rules.ruleset index 6e60c71e4..64b2bc5be 100644 --- a/rules.ruleset +++ b/rules.ruleset @@ -50,46 +50,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/AssemblyFile.cs b/src/ApiPort/ApiPort.VisualStudio.Common/AssemblyFile.cs index 0c17d050d..77a6bd24d 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/AssemblyFile.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/AssemblyFile.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.Fx.Portability; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; -using Microsoft.Fx.Portability; namespace ApiPortVS { diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs index 4f563a54f..973d1d8dc 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.TextManager.Interop; +using System; namespace ApiPortVS.SourceMapping { diff --git a/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs b/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs index 69aecee47..9647dea98 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs +++ b/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs @@ -28,7 +28,8 @@ public class ApiPortVSPackage : Package, IResultToolbar internal static IServiceProvider LocalServiceProvider { get { return s_serviceProvider; } } - public ApiPortVSPackage() : base() + public ApiPortVSPackage() + : base() { s_serviceProvider = new ServiceProvider(this); _assemblyResolver = s_serviceProvider.GetService(typeof(AssemblyRedirectResolver)) as AssemblyRedirectResolver; @@ -107,7 +108,7 @@ public async System.Threading.Tasks.Task ShowToolbarAsync() await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); ToolWindowPane window = FindToolWindow(typeof(AnalysisOutputToolWindow), 0, true); - if ((null == window) || (null == window.Frame)) + if ((window == null) || (window.Frame == null)) { throw new NotSupportedException(LocalizedStrings.CannotCreateToolWindow); } diff --git a/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs b/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs index 23670397d..ce478dc4b 100644 --- a/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs +++ b/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs @@ -24,12 +24,12 @@ internal class AssemblyRedirectResolver public AssemblyRedirectResolver(string configFile) { - var xml = XDocument.Load(configFile); - Func getFullName = (name) => { return XName.Get(name, "urn:schemas-microsoft-com:asm.v1"); }; + XName GetFullName(string name) { return XName.Get(name, "urn:schemas-microsoft-com:asm.v1"); } - var redirects = from element in xml.Descendants(getFullName("dependentAssembly")) - let identity = element.Element(getFullName("assemblyIdentity")) - let redirect = element.Element(getFullName("bindingRedirect")) + var xml = XDocument.Load(configFile); + var redirects = from element in xml.Descendants(GetFullName("dependentAssembly")) + let identity = element.Element(GetFullName("assemblyIdentity")) + let redirect = element.Element(GetFullName("bindingRedirect")) let name = identity.Attribute("name").Value let publicKey = identity.Attribute("publicKeyToken").Value let newVersion = redirect.Attribute("newVersion").Value @@ -43,7 +43,7 @@ public AssemblyRedirectResolver(DirectoryInfo assemblyFolder) var redirects = assemblyFolder.GetFiles("*.dll") .Select(dll => { var name = AssemblyName.GetAssemblyName(dll.FullName); - var publicKeyToken = name.GetPublicKeyToken().Aggregate("", (s, b) => s += b.ToString("x2", CultureInfo.InvariantCulture)); + var publicKeyToken = name.GetPublicKeyToken().Aggregate(string.Empty, (s, b) => s += b.ToString("x2", CultureInfo.InvariantCulture)); return new AssemblyRedirect(name.Name, name.Version.ToString(), publicKeyToken); }); @@ -55,9 +55,7 @@ public Assembly ResolveAssembly(string assemblyName, Assembly requestingAssembly // Use latest strong name & version when trying to load SDK assemblies var requestedAssembly = new AssemblyName(assemblyName); - AssemblyRedirect redirectInformation; - - if (!_redirectsDictionary.TryGetValue(requestedAssembly.Name, out redirectInformation)) + if (!_redirectsDictionary.TryGetValue(requestedAssembly.Name, out var redirectInformation)) { return null; } @@ -72,7 +70,7 @@ public Assembly ResolveAssembly(string assemblyName, Assembly requestingAssembly && redirectInformation.TargetVersion.Equals(assm.Version); }); - if (alreadyLoadedAssembly != default(Assembly)) + if (alreadyLoadedAssembly != default) { return alreadyLoadedAssembly; } diff --git a/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs b/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs index a9f5074c7..b52ef586a 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs +++ b/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs @@ -28,9 +28,9 @@ namespace ApiPortVS { internal sealed class ServiceProvider : IDisposable, IServiceProvider { - private static Guid OutputWindowGuid = new Guid(0xe2fc797f, 0x1dd3, 0x476c, 0x89, 0x17, 0x86, 0xcd, 0x31, 0x33, 0xc4, 0x69); - private static readonly DirectoryInfo AssemblyDirectory = new FileInfo(typeof(ServiceProvider).Assembly.Location).Directory; private const string DefaultEndpoint = @"https://portability.dot.net/"; + private static readonly DirectoryInfo AssemblyDirectory = new FileInfo(typeof(ServiceProvider).Assembly.Location).Directory; + private static Guid OutputWindowGuid = new Guid(0xe2fc797f, 0x1dd3, 0x476c, 0x89, 0x17, 0x86, 0xcd, 0x31, 0x33, 0xc4, 0x69); private readonly IContainer _container; diff --git a/src/ApiPort/ApiPort.VisualStudio/StatusBarProgressReporter.cs b/src/ApiPort/ApiPort.VisualStudio/StatusBarProgressReporter.cs index 3e7f4aaee..4d74e9fd9 100644 --- a/src/ApiPort/ApiPort.VisualStudio/StatusBarProgressReporter.cs +++ b/src/ApiPort/ApiPort.VisualStudio/StatusBarProgressReporter.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.IO; using ApiPortVS.Resources; using Microsoft.Fx.Portability; using Microsoft.VisualStudio.Shell.Interop; +using System.IO; namespace ApiPortVS { diff --git a/src/ApiPort/ApiPort.VisualStudio/Views/AnalysisOutputToolWindow.cs b/src/ApiPort/ApiPort.VisualStudio/Views/AnalysisOutputToolWindow.cs index de022de1a..9d12ed37d 100644 --- a/src/ApiPort/ApiPort.VisualStudio/Views/AnalysisOutputToolWindow.cs +++ b/src/ApiPort/ApiPort.VisualStudio/Views/AnalysisOutputToolWindow.cs @@ -26,7 +26,8 @@ public class AnalysisOutputToolWindow : ToolWindowPane /// /// Initializes a new instance of the class. /// - public AnalysisOutputToolWindow() : base(null) + public AnalysisOutputToolWindow() + : base(null) { var viewModel = ApiPortVSPackage.LocalServiceProvider.GetService(typeof(OutputViewModel)) as OutputViewModel; this.Caption = LocalizedStrings.PortabilityAnalysisResults; diff --git a/src/ApiPort/ApiPort/ConsoleApiPort.cs b/src/ApiPort/ApiPort/ConsoleApiPort.cs index 7334bdece..5cccec9d6 100644 --- a/src/ApiPort/ApiPort/ConsoleApiPort.cs +++ b/src/ApiPort/ApiPort/ConsoleApiPort.cs @@ -84,7 +84,7 @@ public async Task ListTargetsAsync() foreach (var item in expandableTargets) { - Console.WriteLine(LocalizedStrings.TargetsListGrouped, item.Name, String.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator + " ", item.ExpandedTargets)); + Console.WriteLine(LocalizedStrings.TargetsListGrouped, item.Name, string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator + " ", item.ExpandedTargets)); } } } diff --git a/src/ApiPort/ApiPort/ConsoleProgressReporter.cs b/src/ApiPort/ApiPort/ConsoleProgressReporter.cs index 26650d073..2676b1aa5 100644 --- a/src/ApiPort/ApiPort/ConsoleProgressReporter.cs +++ b/src/ApiPort/ApiPort/ConsoleProgressReporter.cs @@ -105,8 +105,7 @@ public void Dispose() private sealed class ConsoleProgressTask : IProgressTask { private static readonly TimeSpan MaxWaitTime = TimeSpan.FromMinutes(10); - - private readonly static char[] s_chars = new char[] { '-', '\\', '|', '/' }; + private static readonly char[] InProgressCharacters = new char[] { '-', '\\', '|', '/' }; private readonly Task _animationTask; diff --git a/src/ApiPort/ApiPort/Program.cs b/src/ApiPort/ApiPort/Program.cs index 640104ac5..0727e06a3 100644 --- a/src/ApiPort/ApiPort/Program.cs +++ b/src/ApiPort/ApiPort/Program.cs @@ -212,7 +212,7 @@ private static bool IsWebSecurityFailureOnMono(Exception ex) { var errorType = ex.InnerException.InnerException.InnerException.GetType(); - if (String.Equals(errorType.FullName, "Mono.Security.Protocol.Tls.TlsException", StringComparison.Ordinal)) + if (string.Equals(errorType.FullName, "Mono.Security.Protocol.Tls.TlsException", StringComparison.Ordinal)) { Console.WriteLine(LocalizedStrings.MonoWebRequestsFailure); diff --git a/src/ApiPort/ApiPort/Proxy/WebProxy.cs b/src/ApiPort/ApiPort/Proxy/WebProxy.cs index d4276251c..9f8633e03 100644 --- a/src/ApiPort/ApiPort/Proxy/WebProxy.cs +++ b/src/ApiPort/ApiPort/Proxy/WebProxy.cs @@ -62,7 +62,7 @@ public bool IsBypassed(Uri uri) if (_regExBypassList != null && _regExBypassList.Length > 0) { - var normalizedUri = uri.Scheme + "://" + uri.Host + ((!uri.IsDefaultPort) ? (":" + uri.Port) : ""); + var normalizedUri = uri.Scheme + "://" + uri.Host + ((!uri.IsDefaultPort) ? (":" + uri.Port) : string.Empty); return _regExBypassList.Any(r => r.IsMatch(normalizedUri)); } diff --git a/src/lib/Microsoft.Fx.Portability.Cci/AssemblyIdentityHelpers.cs b/src/lib/Microsoft.Fx.Portability.Cci/AssemblyIdentityHelpers.cs index 7f32d3c16..359b8ab8c 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/AssemblyIdentityHelpers.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/AssemblyIdentityHelpers.cs @@ -42,7 +42,7 @@ public static AssemblyIdentity Parse(INameTable nameTable, string formattedName) #if FEATURE_ASSEMBLYNAME_CODEBASE name.CodeBase); #else - ""); + string.Empty); #endif } } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs index 82cfe5e9b..6d991e661 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.Fx.Portability.Analyzer.Resources; using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -8,7 +9,6 @@ using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Text; -using Microsoft.Fx.Portability.Analyzer.Resources; namespace Microsoft.Fx.Portability.Analyzer { @@ -144,7 +144,7 @@ public MemberMetadataInfo GetFullName(TypeReference reference, TypeReference? ch { return new MemberMetadataInfo(name) { - DefinedInAssembly = Reader.GetAssemblyReference((AssemblyReferenceHandle)(scope)) + DefinedInAssembly = Reader.GetAssemblyReference((AssemblyReferenceHandle)scope) }; } else @@ -158,12 +158,12 @@ public MemberMetadataInfo GetFullName(TypeReference reference, TypeReference? ch // Some obfuscators will inject impossible types that are each others' scopes // in order to foil decompilers. Check for that case so that we can fail reasonably // instead of stack overflowing. - if (Reader.GetTypeReference((TypeReferenceHandle)(scope)).Equals(child.Value)) + if (Reader.GetTypeReference((TypeReferenceHandle)scope).Equals(child.Value)) { throw new BadImageFormatException(LocalizedStrings.InfiniteTypeParentingRecursion); } } - MemberMetadataInfo info2 = GetFullName(Reader.GetTypeReference((TypeReferenceHandle)(scope)), reference); + MemberMetadataInfo info2 = GetFullName(Reader.GetTypeReference((TypeReferenceHandle)scope), reference); return new MemberMetadataInfo(name, info2); default: diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs index cfb58f870..ddfdd41bc 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MetadataReaderExtensions.cs @@ -140,7 +140,7 @@ private static string FormatPublicKeyToken(this MetadataReader metadataReader, B // Convert bytes to string, but we don't want the '-' characters and need it to be lower case return BitConverter.ToString(bytes) - .Replace("-", "") + .Replace("-", string.Empty) .ToLowerInvariant(); } diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs index 67455336c..56811ec09 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs @@ -161,7 +161,7 @@ private void GenerateSummaryPage(Worksheet summaryPage, ReportingResult analysis var summaryData = new List() { 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)))); + summaryData.AddRange(item.UsageData.Select(pui => (object)Math.Round(pui.PortabilityIndex * 100.0, 2))); summaryPage.AddRow(summaryData.ToArray()); tableRowCount++; } @@ -206,7 +206,7 @@ private static void GenerateUnreferencedAssembliesPage(Worksheet missingAssembli } else { - missingAssembliesPage.AddRow(unresolvedAssemblyPair.Key, String.Empty, LocalizedStrings.UnresolvedUsedAssembly); + missingAssembliesPage.AddRow(unresolvedAssemblyPair.Key, string.Empty, LocalizedStrings.UnresolvedUsedAssembly); } } @@ -295,10 +295,12 @@ private void GenerateDetailsPage(Worksheet detailsPage, ReportingResult analysis detailsPage.AddTable(1, detailsRows, 1, detailsPageHeader.ToArray()); // Generate the columns - List columnWidths = new List(); - columnWidths.Add(ColumnWidths.DetailsPage.TargetType); // Target type - columnWidths.Add(ColumnWidths.DetailsPage.TargetMember); // Target member - columnWidths.Add(ColumnWidths.DetailsPage.AssemblyName); // Assembly name + var columnWidths = new List + { + 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 diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs index 835b66e26..4fa905bea 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs @@ -68,8 +68,10 @@ public static Table AddTable(this Worksheet worksheet, int rowStart, int rowCoun // use unique ids for tables. uint tableID = IncrementalUniqueId; - var tp = new TablePart(); - tp.Id = worksheet.WorksheetPart.GetIdOfPart(tableDefPart); + var tp = new TablePart + { + Id = worksheet.WorksheetPart.GetIdOfPart(tableDefPart) + }; var tableParts = worksheet.GetFirstChild(); if (tableParts == null) tableParts = worksheet.AppendChild(new TableParts()); @@ -91,8 +93,10 @@ public static Table AddTable(this Worksheet worksheet, int rowStart, int rowCoun tc.AppendChild(new TableColumn() { Id = i + 1, Name = headers[i] }); } - tableDefPart.Table.AutoFilter = new AutoFilter(); - tableDefPart.Table.AutoFilter.Reference = range; + tableDefPart.Table.AutoFilter = new AutoFilter + { + Reference = range + }; var styleInfo = tableDefPart.Table.AppendChild(new TableStyleInfo()); styleInfo.Name = "TableStyleMedium2"; @@ -200,7 +204,7 @@ private static string GetCellRefence(SheetData sd, Row row) // Column needs to be 0-based for the GetColumnName method var columnCount = row.Descendants().Count() - 1; - return String.Format(CultureInfo.CurrentCulture, "{0}{1}", GetColumnName(columnCount), rowCount); + return string.Format(CultureInfo.CurrentCulture, "{0}{1}", GetColumnName(columnCount), rowCount); } /// diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs index 7bf325ad9..1e1af971b 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs @@ -3,15 +3,15 @@ using Microsoft.Fx.Portability.ObjectModel; using Microsoft.Fx.Portability.Reporting; +using Microsoft.Fx.Portability.Reports.Html; +using Microsoft.Fx.Portability.Reports.Html.Resources; using RazorEngine.Configuration; using RazorEngine.Templating; using RazorEngine.Text; +using System; using System.IO; using System.Reflection; using System.Text; -using System; -using Microsoft.Fx.Portability.Reports.Html; -using Microsoft.Fx.Portability.Reports.Html.Resources; using static System.FormattableString; @@ -123,7 +123,7 @@ public IEncodedString TargetSupportCell(TargetSupportedIn supportStatus) public IEncodedString BreakingChangeCountCell(int breaks, int warningThreshold, int errorThreshold) { - var className = ""; + var className = string.Empty; if (breaks <= warningThreshold) { className = "NoBreakingChanges"; diff --git a/src/lib/Microsoft.Fx.Portability/AliasMappedToMultipleNamesException.cs b/src/lib/Microsoft.Fx.Portability/AliasMappedToMultipleNamesException.cs index 64e39ad4c..128b83e04 100644 --- a/src/lib/Microsoft.Fx.Portability/AliasMappedToMultipleNamesException.cs +++ b/src/lib/Microsoft.Fx.Portability/AliasMappedToMultipleNamesException.cs @@ -1,16 +1,15 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; +using Microsoft.Fx.Portability.Resources; using System.Collections.Generic; using System.Globalization; -using Microsoft.Fx.Portability.Resources; namespace Microsoft.Fx.Portability { public class AliasMappedToMultipleNamesException : PortabilityAnalyzerException { - private static string s_listSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator + " "; + private static readonly string s_listSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator + " "; private static string GenerateMessage(IEnumerable invalidNames) { diff --git a/src/lib/Microsoft.Fx.Portability/ApiPortService.cs b/src/lib/Microsoft.Fx.Portability/ApiPortService.cs index b4fffcd56..57cf2c673 100644 --- a/src/lib/Microsoft.Fx.Portability/ApiPortService.cs +++ b/src/lib/Microsoft.Fx.Portability/ApiPortService.cs @@ -177,7 +177,7 @@ private static HttpMessageHandler BuildMessageHandler(string endpoint, IProxyPro SslProtocols = CompressedHttpClient.SupportedSSLProtocols, #endif Proxy = proxyProvider?.GetProxy(uri), - AutomaticDecompression = (DecompressionMethods.GZip | DecompressionMethods.Deflate) + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; if (clientHandler.Proxy == null) diff --git a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs index 02a346cef..266caa234 100644 --- a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs +++ b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs @@ -65,7 +65,7 @@ public static IEnumerable FromMarkdown(Stream stream, IEnumerabl BreakingChange currentBreak = null; string currentLine; - while (null != (currentLine = sr.ReadLine())) + while ((currentLine = sr.ReadLine()) != null) { currentLine = currentLine.Trim(); @@ -283,7 +283,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState } else { - currentBreak.Details += ("\n" + currentLine); + currentBreak.Details += "\n" + currentLine; } break; case ParseState.Suggestion: @@ -293,24 +293,27 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState } else { - currentBreak.Suggestion += ("\n" + currentLine); + currentBreak.Suggestion += "\n" + currentLine; } break; case ParseState.Notes: // Special-case the fact that 'notes' will often come at the end of a comment section and we don't need the closing --> in the note. - if (string.Equals("-->", currentLine.Trim(), StringComparison.Ordinal)) return; + if (string.Equals("-->", currentLine.Trim(), StringComparison.Ordinal)) + { + return; + } + if (currentBreak.Notes == null) { currentBreak.Notes = currentLine; } else { - currentBreak.Notes += ("\n" + currentLine); + currentBreak.Notes += "\n" + currentLine; } break; case ParseState.SourceAnalyzerStatus: - BreakingChangeAnalyzerStatus status; - if (Enum.TryParse(currentLine.Trim().Replace(" ", ""), true, out status)) + if (Enum.TryParse(currentLine.Trim().Replace(" ", string.Empty), true, out var status)) { currentBreak.SourceAnalyzerStatus = status; } diff --git a/src/lib/Microsoft.Fx.Portability/MovedPermanentlyException.cs b/src/lib/Microsoft.Fx.Portability/MovedPermanentlyException.cs index ed52eb6ab..59b3d3afa 100644 --- a/src/lib/Microsoft.Fx.Portability/MovedPermanentlyException.cs +++ b/src/lib/Microsoft.Fx.Portability/MovedPermanentlyException.cs @@ -7,6 +7,9 @@ namespace Microsoft.Fx.Portability { public class MovedPermanentlyException : PortabilityAnalyzerException { - public MovedPermanentlyException() : base(LocalizedStrings.ServerEndpointMovedPermanently) { } + public MovedPermanentlyException() + : base(LocalizedStrings.ServerEndpointMovedPermanently) + { + } } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/AncestorApiRecommendations.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/AncestorApiRecommendations.cs index 2165e85cf..2d5b8dee7 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/AncestorApiRecommendations.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/AncestorApiRecommendations.cs @@ -62,7 +62,7 @@ string IApiRecommendations.GetComponent(string docId) protected virtual string GetComponent(string docId) { - return String.Empty; + return string.Empty; } IEnumerable IApiRecommendations.GetBreakingChanges(string docId) diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfoList.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfoList.cs index a343be068..ccf4696ff 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfoList.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfoList.cs @@ -1,13 +1,12 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using System.IO; -using System.Reflection; -using Newtonsoft.Json; +using System.Linq; namespace Microsoft.Fx.Portability.ObjectModel { @@ -59,12 +58,12 @@ public void Load(IEnumerable inputs) public IEnumerator GetEnumerator() { - return _innerList == null ? null : _innerList.GetEnumerator(); + return _innerList?.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { - return ((IEnumerable)_innerList) == null ? null : ((IEnumerable)_innerList).GetEnumerator(); + return ((IEnumerable)_innerList)?.GetEnumerator(); } } } diff --git a/src/lib/Microsoft.Fx.Portability/Proxy/ProxyAuthenticationHandler.cs b/src/lib/Microsoft.Fx.Portability/Proxy/ProxyAuthenticationHandler.cs index 0a8629c32..4b8f9f17d 100644 --- a/src/lib/Microsoft.Fx.Portability/Proxy/ProxyAuthenticationHandler.cs +++ b/src/lib/Microsoft.Fx.Portability/Proxy/ProxyAuthenticationHandler.cs @@ -20,8 +20,8 @@ namespace Microsoft.Fx.Portability.Proxy /// public class ProxyAuthenticationHandler : DelegatingHandler { - public static readonly int MaxAttempts = 3; private const string BasicAuthenticationType = "Basic"; + public static readonly int MaxAttempts = 3; private readonly HttpClientHandler _clientHandler; private readonly IProxyProvider _proxyProvider; diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs index a75fb109d..a377caca4 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs @@ -1,18 +1,18 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.Fx.Portability.ObjectModel; +using Microsoft.Fx.Portability.Resources; using System; using System.Collections.Generic; using System.Linq; -using Microsoft.Fx.Portability.Resources; -using Microsoft.Fx.Portability.ObjectModel; namespace Microsoft.Fx.Portability.Reporting.ObjectModel { public class MissingTypeInfo : MissingInfo { - private bool _isMissing; private readonly HashSet _usedInAssemblies; + private bool _isMissing; public int UsageCount { get { return _usedInAssemblies.Count; } } diff --git a/src/lib/Microsoft.Fx.Portability/RequestTooLargeException.cs b/src/lib/Microsoft.Fx.Portability/RequestTooLargeException.cs index 15005ca56..897c0c104 100644 --- a/src/lib/Microsoft.Fx.Portability/RequestTooLargeException.cs +++ b/src/lib/Microsoft.Fx.Portability/RequestTooLargeException.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Globalization; using Microsoft.Fx.Portability.Resources; +using System.Globalization; namespace Microsoft.Fx.Portability { diff --git a/src/lib/Microsoft.Fx.Portability/TargetMapper.cs b/src/lib/Microsoft.Fx.Portability/TargetMapper.cs index 8d0c6fbe3..949c7fa2f 100644 --- a/src/lib/Microsoft.Fx.Portability/TargetMapper.cs +++ b/src/lib/Microsoft.Fx.Portability/TargetMapper.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.Fx.Portability.Resources; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -10,7 +11,6 @@ using System.Runtime.Versioning; using System.Xml; using System.Xml.Linq; -using Microsoft.Fx.Portability.Resources; #if FEATURE_XML_SCHEMA using System.Xml.Schema; diff --git a/src/lib/Microsoft.Fx.Portability/TargetMapperException.cs b/src/lib/Microsoft.Fx.Portability/TargetMapperException.cs index ed872e339..1c3b89ad9 100644 --- a/src/lib/Microsoft.Fx.Portability/TargetMapperException.cs +++ b/src/lib/Microsoft.Fx.Portability/TargetMapperException.cs @@ -7,8 +7,14 @@ namespace Microsoft.Fx.Portability { public class TargetMapperException : PortabilityAnalyzerException { - public TargetMapperException(string message) : base(message) { } + public TargetMapperException(string message) + : base(message) + { + } - public TargetMapperException(string message, Exception innerException) : base(message, innerException) { } + public TargetMapperException(string message, Exception innerException) + : base(message, innerException) + { + } } } diff --git a/src/lib/Microsoft.Fx.Portability/UnknownTargetException.cs b/src/lib/Microsoft.Fx.Portability/UnknownTargetException.cs index 060a1185f..1d620a8f2 100644 --- a/src/lib/Microsoft.Fx.Portability/UnknownTargetException.cs +++ b/src/lib/Microsoft.Fx.Portability/UnknownTargetException.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Globalization; using Microsoft.Fx.Portability.Resources; +using System.Globalization; namespace Microsoft.Fx.Portability { @@ -10,7 +10,8 @@ public class UnknownTargetException : PortabilityAnalyzerException { public string TargetName { get; set; } - public UnknownTargetException(string targetName) : base(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnknownTarget, targetName)) + public UnknownTargetException(string targetName) + : base(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnknownTarget, targetName)) { TargetName = targetName; } diff --git a/src/lib/Microsoft.Fx.Portability/UrlBuilder.cs b/src/lib/Microsoft.Fx.Portability/UrlBuilder.cs index db931cecb..dd735fc8a 100644 --- a/src/lib/Microsoft.Fx.Portability/UrlBuilder.cs +++ b/src/lib/Microsoft.Fx.Portability/UrlBuilder.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.Fx.Portability.Resources; using System; -using System.Linq; using System.Collections.Generic; using System.Globalization; -using Microsoft.Fx.Portability.Resources; +using System.Linq; namespace Microsoft.Fx.Portability { diff --git a/tests/ApiPort/ApiPortVS.Tests/ProjectBuilderTests.cs b/tests/ApiPort/ApiPortVS.Tests/ProjectBuilderTests.cs index e5f73f580..40fcf8918 100644 --- a/tests/ApiPort/ApiPortVS.Tests/ProjectBuilderTests.cs +++ b/tests/ApiPort/ApiPortVS.Tests/ProjectBuilderTests.cs @@ -1,15 +1,13 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Threading.Tasks; +using ApiPortVS.Contracts; using EnvDTE; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell.Interop; using NSubstitute; -using Xunit; using System.Collections.Generic; -using ApiPortVS.Contracts; +using Xunit; namespace ApiPortVS.Tests { @@ -23,7 +21,6 @@ public static void Build_VsFailsToStartBuild_TaskResultSetFalse() var mapper = Substitute.For(); var threading = Substitute.For(); var projectBuilder = new DefaultProjectBuilder(buildManager, threading, mapper); - uint pdwCookie; var result = projectBuilder.BuildAsync(new List { project }).Result; @@ -32,7 +29,7 @@ public static void Build_VsFailsToStartBuild_TaskResultSetFalse() // Checking that we are not listening to build events // if starting a build was not successful buildManager.DidNotReceiveWithAnyArgs() - .AdviseUpdateSolutionEvents(null, out pdwCookie); + .AdviseUpdateSolutionEvents(null, out var pdwCookie); } [Fact] @@ -44,13 +41,11 @@ public static void Build_BuildCompletedSuccessfully_TaskResultSetTrue() var threading = Substitute.For(); var projectBuilder = new DefaultProjectBuilder(buildManager, threading, mapper); - uint pdwCookie; - var buildTask = projectBuilder.BuildAsync(new List { project }); // Checking that we are subscribed to build events buildManager.ReceivedWithAnyArgs(1) - .AdviseUpdateSolutionEvents(Arg.Any(), out pdwCookie); + .AdviseUpdateSolutionEvents(Arg.Any(), out var pdwCookie); } private static IVsSolutionBuildManager2 BuildManagerWhichReturns(int returnForUpdate) @@ -59,9 +54,7 @@ private static IVsSolutionBuildManager2 BuildManagerWhichReturns(int returnForUp buildManager.StartUpdateSpecificProjectConfigurations(default, null, null, null, null, null, default, default) .ReturnsForAnyArgs(returnForUpdate); - uint cookie; - - buildManager.AdviseUpdateSolutionEvents(null, out cookie) + buildManager.AdviseUpdateSolutionEvents(null, out var cookie) .ReturnsForAnyArgs(4); return buildManager; diff --git a/tests/ApiPort/ApiPortVS.Tests/TestAssemblyFile.cs b/tests/ApiPort/ApiPortVS.Tests/TestAssemblyFile.cs index 8c02338f8..b64681b14 100644 --- a/tests/ApiPort/ApiPortVS.Tests/TestAssemblyFile.cs +++ b/tests/ApiPort/ApiPortVS.Tests/TestAssemblyFile.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.Fx.Portability; using System; using System.IO; -using Microsoft.Fx.Portability; namespace ApiPortVS.Tests { diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/CciAnalyzerTests.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/CciAnalyzerTests.cs index 4ddb909b3..ffeb2ac80 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/CciAnalyzerTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/CciAnalyzerTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.Fx.Portability.Analyzer; +using NSubstitute; using System; using System.Collections.Generic; using System.Linq; -using Microsoft.Fx.Portability.Analyzer; -using NSubstitute; using Xunit; namespace Microsoft.Fx.Portability.Cci.Tests diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs index c0783c553..83137ab7a 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs @@ -1,18 +1,18 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Collections.Generic; -using System.Linq; using Microsoft.Fx.Portability.Analyzer; using NSubstitute; +using System.Collections.Generic; +using System.Linq; using Xunit; namespace Microsoft.Fx.Portability.Cci.Tests { public class ManagedMetadataReaderTests { - private readonly static string s_emptyProjectPath = TestAssembly.EmptyProject; - private readonly static string s_withGenericsAndReferencePath = TestAssembly.WithGenericsAndReference; + private static readonly string s_emptyProjectPath = TestAssembly.EmptyProject; + private static readonly string s_withGenericsAndReferencePath = TestAssembly.WithGenericsAndReference; [Fact] public static void EmptyProject() diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs index c3a18aa8b..f71d573dc 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs @@ -16,14 +16,14 @@ namespace Microsoft.Fx.Portability.Cci.Tests { internal class TestAssembly { + private const string TFM = @"[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")]"; private static readonly string s_mscorlib = typeof(object).GetTypeInfo().Assembly.Location; private readonly string _path; - private const string TFM = @"[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")]"; private TestAssembly(string assemblyName, string text, IEnumerable referencePaths) { var executableName = Invariant($"{assemblyName}-{Guid.NewGuid()}.exe"); - var path = new FileInfo(Path.Combine(Path.GetTempPath(), executableName)); + var path = new FileInfo(System.IO.Path.Combine(System.IO.Path.GetTempPath(), executableName)); _path = path.FullName; if (path.Exists) @@ -49,14 +49,14 @@ private TestAssembly(string assemblyName, string text, IEnumerable refer Assert.True(result.Success); } - public string path { get { return _path; } } + public string Path { get { return _path; } } public static string EmptyProject { get { var text = GetText("EmptyProject.cs"); - return new TestAssembly("EmptyProject", text, new[] { s_mscorlib }).path; + return new TestAssembly("EmptyProject", text, new[] { s_mscorlib }).Path; } } @@ -65,7 +65,7 @@ public static string WithGenericsAndReference get { var text = GetText("WithGenericsAndReference.cs"); - return new TestAssembly("WithGenericsAndReference", text, new[] { s_mscorlib, EmptyProject }).path; + return new TestAssembly("WithGenericsAndReference", text, new[] { s_mscorlib, EmptyProject }).Path; } } diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssemblyFile.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssemblyFile.cs index f8b877ca9..71f7c9783 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssemblyFile.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssemblyFile.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using Microsoft.Fx.Portability; namespace Microsoft.Fx.Portability.Cci.Tests { diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs index 73149a9b2..f29803fb6 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs @@ -62,13 +62,12 @@ public StringAssemblyFile(string name, string contents) private class CSharpCompileAssemblyFile : ResourceStreamAssemblyFile { + private const string TFM = @"[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")]"; private static readonly IEnumerable s_references = new[] { typeof(object).GetTypeInfo().Assembly.Location, typeof(Uri).GetTypeInfo().Assembly.Location, typeof(Console).GetTypeInfo().Assembly.Location } .Distinct() .Select(r => MetadataReference.CreateFromFile(r)) .ToList(); - private const string TFM = @"[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")]"; - private readonly bool _allowUnsafe; private readonly IEnumerable _additionalReferences; diff --git a/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs b/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs index 758770891..16b63598a 100644 --- a/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs @@ -122,7 +122,7 @@ public async Task QueryDocIdsWithOneItemEmptyString() $"T:{ValidDocId}0", $"T:{ValidDocId}1", $"P:{ValidDocId}1", - "", + string.Empty, $"{InvalidDocId}{MaxDocIdSetCount + 1}", $"{InvalidDocId}{MaxDocIdSetCount + 2}", $"{InvalidDocId}{MaxDocIdSetCount + 3}", diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs index b1fa503c6..fd92e7362 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs @@ -16,6 +16,9 @@ namespace Microsoft.Fx.Portability.Web.Analyze.Tests { public class AnalysisEngineTests { + private const string TestDocId1 = "T:System.Drawing.Color"; + private const string TestDocId2 = "T:System.Data.SqlTypes.SqlBoolean"; + #region FindUnreferencedAssemblies private static List s_unreferencedAssemblies = new List() @@ -67,7 +70,7 @@ public static void FindUnreferencedAssemblies_UnreferencedAssemblies_1() var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); - var specifiedUserAssemblies = new[] { new AssemblyInfo { FileVersion = "", AssemblyIdentity = "MyAssembly" } }; + var specifiedUserAssemblies = new[] { new AssemblyInfo { FileVersion = string.Empty, AssemblyIdentity = "MyAssembly" } }; var unreferencedAssms = engine.FindUnreferencedAssemblies(s_unreferencedAssemblies, specifiedUserAssemblies).ToList(); // 0 missing assembly since Microsoft.CSharp is a FX assembly and we specified MyAssembly @@ -98,7 +101,7 @@ public static void FindUnreferencedAssemblies_UnreferencedAssemblies_WithNullInS var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); - var specifiedUserAssemblies = new List() { new AssemblyInfo() { FileVersion = "", AssemblyIdentity = "MyAssembly" }, null }; + var specifiedUserAssemblies = new List() { new AssemblyInfo() { FileVersion = string.Empty, AssemblyIdentity = "MyAssembly" }, null }; var unreferencedAssms = engine.FindUnreferencedAssemblies(s_unreferencedAssemblies, specifiedUserAssemblies).ToList(); // 0 missing assembly since Microsoft.CSharp is a fx assembly and we specified MyAssembly @@ -114,7 +117,7 @@ public static void FindUnreferencedAssemblies_UnreferencedAssemblies_WithNullInU var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); - var specifiedUserAssemblies = new List() { new AssemblyInfo() { FileVersion = "", AssemblyIdentity = "MyAssembly" } }; + var specifiedUserAssemblies = new List() { new AssemblyInfo() { FileVersion = string.Empty, AssemblyIdentity = "MyAssembly" } }; var listWithNulls = s_unreferencedAssemblies.Concat(new List() { null }).ToList(); var unreferencedAssms = engine.FindUnreferencedAssemblies(listWithNulls, specifiedUserAssemblies).ToList(); @@ -583,9 +586,6 @@ private static IApiRecommendations GenerateTestRecommendationsForShowRetargettin return recommendations; } - private const string TestDocId1 = "T:System.Drawing.Color"; - private const string TestDocId2 = "T:System.Data.SqlTypes.SqlBoolean"; - private static ICollection GenerateIgnoreAssemblies(bool otherAssm, string[] targetFrameworks) { return new[] diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/TargetNameParserTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/TargetNameParserTests.cs index 1451b50b7..8bad1f6f9 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/TargetNameParserTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/TargetNameParserTests.cs @@ -38,8 +38,8 @@ public static void NoSpecifiedTargets_2() [Fact] public static void CaseInsensitive() { - var parser = new TargetNameParser(new TestCatalog(), String.Empty); - var targets = parser.MapTargetsToExplicitVersions(new String[] { "target 1, version=1.0" }); + var parser = new TargetNameParser(new TestCatalog(), string.Empty); + var targets = parser.MapTargetsToExplicitVersions(new[] { "target 1, version=1.0" }); // We should only have 1 target! Assert.Single(targets); @@ -49,7 +49,7 @@ public static void CaseInsensitive() [Fact] public static void NoSpecifiedDefaultTargets() { - var parser = new TargetNameParser(new TestCatalog(), String.Empty); + var parser = new TargetNameParser(new TestCatalog(), string.Empty); var targets = parser.MapTargetsToExplicitVersions(Enumerable.Empty()); // We should only have 0 target! diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs index bc487763e..7b887f276 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ApiPortServiceTests.cs @@ -33,9 +33,9 @@ public void Dispose() [Fact] public static void VerifyParameterChecks() { - Assert.Throws(() => new ApiPortService(null, new ProductInformation(""))); - Assert.Throws(() => new ApiPortService(string.Empty, new ProductInformation(""))); - Assert.Throws(() => new ApiPortService(" \t", new ProductInformation(""))); + Assert.Throws(() => new ApiPortService(null, new ProductInformation(string.Empty))); + Assert.Throws(() => new ApiPortService(string.Empty, new ProductInformation(string.Empty))); + Assert.Throws(() => new ApiPortService(" \t", new ProductInformation(string.Empty))); } [Fact] @@ -97,8 +97,10 @@ private static HttpResponseMessage HttpRequestConverter(HttpRequestMessage reque var streamContent = new StreamContent(resourceStream); streamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); - response.Content = streamContent; + var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK) + { + Content = streamContent + }; return response; } } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoComparerTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoComparerTests.cs index ded897c8a..b98e79adc 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoComparerTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoComparerTests.cs @@ -21,9 +21,9 @@ public static void SortingTest() var packageId1 = "Remotion.Linq"; var packageId2 = "Antlr3.Runtime"; var packageId3 = "NHibernate"; - var nuget1 = new NuGetPackageInfo(packageId1, new Dictionary(), ""); - var nuget2 = new NuGetPackageInfo(packageId2, new Dictionary(), ""); - var nuget3 = new NuGetPackageInfo(packageId3, new Dictionary(), ""); + var nuget1 = new NuGetPackageInfo(packageId1, new Dictionary(), string.Empty); + var nuget2 = new NuGetPackageInfo(packageId2, new Dictionary(), string.Empty); + var nuget3 = new NuGetPackageInfo(packageId3, new Dictionary(), string.Empty); var nugetList = new List() { nuget1, nuget2, nuget3 }; nugetList.Sort(new NuGetPackageInfoComparer()); diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoTests.cs index 732bc5068..386695735 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/NuGetPackageInfoTests.cs @@ -60,7 +60,7 @@ public static void InvalidConstruction() var packageInfo = new NuGetPackageInfo(package1, new Dictionary { { frameworkName, package1Version } }, assemblyInfo); Assert.Throws(() => new NuGetPackageInfo(null, new Dictionary { { frameworkName, package1Version } }, assemblyInfo)); - Assert.Throws(() => new NuGetPackageInfo("", new Dictionary { { frameworkName, package1Version } }, assemblyInfo)); + Assert.Throws(() => new NuGetPackageInfo(string.Empty, new Dictionary { { frameworkName, package1Version } }, assemblyInfo)); Assert.Throws(() => new NuGetPackageInfo(package1, new Dictionary { { null, package1Version } }, assemblyInfo)); } } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/TargetInformationTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/TargetInformationTests.cs index 0e566e013..a816482b2 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/TargetInformationTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/TargetInformationTests.cs @@ -3,13 +3,8 @@ using Microsoft.Fx.Portability.ObjectModel; using Microsoft.Fx.Portability.Resources; -using Xunit; -using System; -using System.Collections.Generic; using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Xunit; namespace Microsoft.Fx.Portability.Tests.ObjectModel { @@ -42,7 +37,7 @@ public static void ToStringWithExpandedTargets() var expandedTargets = new[] { expanded1, expanded2 }; var info = new TargetInformation { Name = group, ExpandedTargets = expandedTargets }; - var groupedToString = String.Format(CultureInfo.CurrentCulture, LocalizedStrings.TargetInformationGroups, group, String.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator + " ", expandedTargets)); + var groupedToString = string.Format(CultureInfo.CurrentCulture, LocalizedStrings.TargetInformationGroups, group, string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator + " ", expandedTargets)); Assert.Equal(groupedToString, info.ToString()); } } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/SerializationTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/SerializationTests.cs index 4330884c1..9635ac3ef 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/SerializationTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/SerializationTests.cs @@ -93,11 +93,12 @@ public static void TestEmptyValues() private static IDictionary> GetDependencies() { - var dict = new Dictionary>(); - - dict.Add(new MemberInfo { MemberDocId = "item1" }, new HashSet { new AssemblyInfo { AssemblyIdentity = "string1" }, new AssemblyInfo { AssemblyIdentity = "string2" } }); - dict.Add(new MemberInfo { MemberDocId = "item2" }, new HashSet { new AssemblyInfo { AssemblyIdentity = "string3" }, new AssemblyInfo { AssemblyIdentity = "string4" } }); - dict.Add(new MemberInfo { MemberDocId = "item3" }, new HashSet { new AssemblyInfo { AssemblyIdentity = "string5" }, new AssemblyInfo { AssemblyIdentity = "string6" } }); + var dict = new Dictionary> + { + { new MemberInfo { MemberDocId = "item1" }, new HashSet { new AssemblyInfo { AssemblyIdentity = "string1" }, new AssemblyInfo { AssemblyIdentity = "string2" } } }, + { new MemberInfo { MemberDocId = "item2" }, new HashSet { new AssemblyInfo { AssemblyIdentity = "string3" }, new AssemblyInfo { AssemblyIdentity = "string4" } } }, + { new MemberInfo { MemberDocId = "item3" }, new HashSet { new AssemblyInfo { AssemblyIdentity = "string5" }, new AssemblyInfo { AssemblyIdentity = "string6" } } } + }; return dict; } @@ -110,7 +111,7 @@ private static void CollectionAssertAreEquivalent(IEnumerable expected, IE private static void VerifyEmptySerialized() where T : class { - var deserialized = "".Serialize().Deserialize(); + var deserialized = string.Empty.Serialize().Deserialize(); Assert.Null(deserialized); } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs index 240fcec73..67eca5039 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs @@ -2,13 +2,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.Fx.Portability.Resources; -using Xunit; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.Versioning; +using Xunit; namespace Microsoft.Fx.Portability.Tests { @@ -58,7 +58,7 @@ public static void AliasEqualsTarget() } catch (TargetMapperException e) { - Assert.Equal(String.Format(CultureInfo.CurrentCulture, LocalizedStrings.AliasCannotBeEqualToTargetNameError, "TestTarget2"), e.Message); + Assert.Equal(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.AliasCannotBeEqualToTargetNameError, "TestTarget2"), e.Message); return; } @@ -267,7 +267,7 @@ public static void XmlAliasSameAsName() } catch (TargetMapperException e) { - Assert.Equal(String.Format(CultureInfo.CurrentCulture, LocalizedStrings.AliasCannotBeEqualToTargetNameError, "TestTarget2"), e.Message); + Assert.Equal(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.AliasCannotBeEqualToTargetNameError, "TestTarget2"), e.Message); return; } @@ -306,7 +306,7 @@ public static void XmlMalformedXml() catch (TargetMapperException e) { Assert.NotNull(e.InnerException); - Assert.Equal(String.Format(CultureInfo.CurrentCulture, LocalizedStrings.MalformedMap, e.InnerException.Message), e.Message); + Assert.Equal(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.MalformedMap, e.InnerException.Message), e.Message); return; } @@ -330,7 +330,7 @@ public static void XmlNotInSchema() { #if FEATURE_XML_SCHEMA Assert.NotNull(e.InnerException); - Assert.Equal(String.Format(CultureInfo.CurrentCulture, e.InnerException.Message), e.Message); + Assert.Equal(string.Format(CultureInfo.CurrentCulture, e.InnerException.Message), e.Message); #else Assert.Equal(String.Format(CultureInfo.CurrentCulture, LocalizedStrings.MalformedMap, string.Empty), e.Message); #endif diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs index cb65fb21f..742f02734 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs @@ -4,8 +4,8 @@ using Microsoft.Fx.Portability.ObjectModel; using System; using System.Collections.Generic; -using System.Runtime.Versioning; using System.Linq; +using System.Runtime.Versioning; namespace Microsoft.Fx.Portability.TestData { @@ -97,8 +97,7 @@ public bool IsMemberInTarget(string docId, FrameworkName targetName, out Version public bool IsMemberInTarget(string docId, FrameworkName targetName) { - Version v; - return IsMemberInTarget(docId, targetName, out v); + return IsMemberInTarget(docId, targetName, out var v); } public string GetRecommendedChange(string docId) From b4b70f33e83108af30527f0b3509bab993fb53b5 Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Thu, 20 Sep 2018 07:16:21 -0700 Subject: [PATCH 09/17] More style cop rule fixes. Part 4 (#708) * Unsuppressing SA1300 - SA1308 * Fixing SA1300 - SA1308 * Unsuppressing SA1311 - SA1401 * Fixing SA1311 - SA1401 * Unsuppressing SA1403 - SA1411 * Fixing SA1403 - SA1411 * Removing unnecessary GlobalSuppressions * Renaming static variables and debug message --- rules.ruleset | 23 ---------------- .../DefaultProjectBuilder.cs | 4 ++- .../IVsHierarchyExtensions.cs | 12 ++++----- .../Models/OptionsModel.cs | 26 +++++++++---------- .../Models/TargetPlatform.cs | 8 +++--- .../SourceMapping/CodeDocumentNavigator.cs | 6 ++--- .../ApiPort.VisualStudio.csproj | 1 - .../ApiPort.VisualStudio/ApiPortVSPackage.cs | 16 ++++++------ .../AssemblyRedirectResolver.cs | 8 +++--- .../GlobalSuppressions.cs | 14 ---------- .../OutputWindowWriter.cs | 4 +-- .../ApiPort.VisualStudio/ServiceProvider.cs | 8 +++--- .../ApiPort/FileOutputApiPortService.cs | 20 +++++++------- .../Analyzer/CciDependencyFinder.cs | 10 +++---- .../MemberMetadataInfo.cs | 2 +- .../MemberMetadataInfoTypeProvider.cs | 5 ++-- .../ReflectionMetadataDependencyFinder.cs | 6 ++--- .../SystemObjectFinder.cs | 6 ++--- .../ExcelOpenXmlOutputWriter.cs | 4 +-- .../OpenXmlExtensions.cs | 22 ++++++++-------- .../HtmlReportWriter.cs | 8 +++--- .../AliasMappedToMultipleNamesException.cs | 4 +-- .../Analysis/AnalysisEngine.cs | 2 +- .../Analyzer/DotNetFrameworkFilter.cs | 8 +++--- .../BreakingChange.cs | 2 +- .../BreakingChangeParser.cs | 4 +-- .../CompressedHttpClient.cs | 3 ++- .../DataExtensions.cs | 6 ++--- .../IAnalysisEngine.cs | 2 +- .../AssemblyReferenceInformation.cs | 6 ++--- .../ObjectModel/NuGetPackageInfo.cs | 8 +++--- .../Proxy/ProxyAuthenticationHandler.cs | 6 ++--- .../Reporting/ObjectModel/MissingTypeInfo.cs | 12 ++++----- .../ManagedMetadataReaderTests.cs | 10 +++---- .../TestAssembly.cs | 6 ++--- .../TestAssembly.cs | 16 ++++++------ .../OffLineApiPortServiceTests.cs | 20 +++++++------- .../Analysis/AnalysisEngineTests.cs | 24 ++++++++--------- .../BreakingChangeParserTests.cs | 14 +++++----- .../TestData/TestCatalog.cs | 2 +- 40 files changed, 165 insertions(+), 203 deletions(-) delete mode 100644 src/ApiPort/ApiPort.VisualStudio/GlobalSuppressions.cs diff --git a/rules.ruleset b/rules.ruleset index 64b2bc5be..045f1265b 100644 --- a/rules.ruleset +++ b/rules.ruleset @@ -55,32 +55,9 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/DefaultProjectBuilder.cs b/src/ApiPort/ApiPort.VisualStudio.Common/DefaultProjectBuilder.cs index de4ac594e..a897d7e3f 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/DefaultProjectBuilder.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/DefaultProjectBuilder.cs @@ -89,7 +89,7 @@ public virtual async Task BuildAsync(IEnumerable projects) return await tcs.Task; } - public virtual async Task> GetBuildOutputFilesAsync(Project project, CancellationToken cancellationToken = default(CancellationToken)) + public virtual async Task> GetBuildOutputFilesAsync(Project project, CancellationToken cancellationToken = default) { var configuration = await ProjectMapper.GetVsProjectConfigurationAsync(project).ConfigureAwait(false); @@ -142,10 +142,12 @@ private class ProjectAsyncBuilder : IVsUpdateSolutionEvents private readonly TaskCompletionSource _completionSource; private readonly IVsSolutionBuildManager _buildManager; +#pragma warning disable SA1401 // Cookie is required by the DefaultProjectBuilder /// /// A cookie used to track this instance in IVsSolutionBuildManager solution events. /// internal uint UpdateSolutionEventsCookie; +#pragma warning restore SA1401 public ProjectAsyncBuilder(IVsSolutionBuildManager manager, TaskCompletionSource completionSource) { diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/IVsHierarchyExtensions.cs b/src/ApiPort/ApiPort.VisualStudio.Common/IVsHierarchyExtensions.cs index dc8a34a1e..ceb42dac0 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/IVsHierarchyExtensions.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/IVsHierarchyExtensions.cs @@ -20,10 +20,10 @@ public static bool IsDotNetProject(this Project project) switch (project.CodeModel.Language) { - case CodeModelLanguageConstants.vsCMLanguageCSharp: - case CodeModelLanguageConstants.vsCMLanguageVB: + case CodeModelLanguageConstants.VsCMLanguageCSharp: + case CodeModelLanguageConstants.VsCMLanguageVB: return true; - case CodeModelLanguageConstants.vsCMLanguageVC: + case CodeModelLanguageConstants.VsCMLanguageVC: return project.IsManagedCppProject(); } @@ -85,9 +85,9 @@ private class ProjectKindConstants /// private static class CodeModelLanguageConstants { - internal const string vsCMLanguageVC = "{B5E9BD32-6D3E-4B5D-925E-8A43B79820B4}"; - internal const string vsCMLanguageVB = "{B5E9BD33-6D3E-4B5D-925E-8A43B79820B4}"; - internal const string vsCMLanguageCSharp = "{B5E9BD34-6D3E-4B5D-925E-8A43B79820B4}"; + internal const string VsCMLanguageVC = "{B5E9BD32-6D3E-4B5D-925E-8A43B79820B4}"; + internal const string VsCMLanguageVB = "{B5E9BD33-6D3E-4B5D-925E-8A43B79820B4}"; + internal const string VsCMLanguageCSharp = "{B5E9BD34-6D3E-4B5D-925E-8A43B79820B4}"; } /// diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/Models/OptionsModel.cs b/src/ApiPort/ApiPort.VisualStudio.Common/Models/OptionsModel.cs index 61f2ba915..841faf702 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/Models/OptionsModel.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/Models/OptionsModel.cs @@ -18,9 +18,9 @@ namespace ApiPortVS.Models /// public class OptionsModel : NotifyPropertyBase { - private static readonly string s_optionsFilePath; - private static readonly string s_defaultOutputDirectory; - private static readonly string s_defaultOutputName; + private static readonly string OptionsFilePath; + private static readonly string DefaultOutputDirectory; + private static readonly string DefaultOutputFileName; private IList _formats; private IList _platforms; @@ -32,17 +32,17 @@ static OptionsModel() var assembly = Assembly.GetExecutingAssembly(); var directory = Path.GetDirectoryName(assembly.Location); - s_defaultOutputName = "ApiPortAnalysis"; - s_defaultOutputDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Portability Analysis"); - s_optionsFilePath = Path.Combine(directory, "options.dat"); + DefaultOutputFileName = "ApiPortAnalysis"; + DefaultOutputDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Portability Analysis"); + OptionsFilePath = Path.Combine(directory, "options.dat"); } public OptionsModel() { _platforms = Array.Empty(); _formats = Array.Empty(); - _outputName = s_defaultOutputName; - _outputDirectory = s_defaultOutputDirectory; + _outputName = DefaultOutputFileName; + _outputDirectory = DefaultOutputDirectory; LastUpdate = DateTimeOffset.MinValue; } @@ -70,16 +70,16 @@ public string OutputDirectory public string DefaultOutputName { get { return _outputName; } - set { UpdateProperty(ref _outputName, string.IsNullOrWhiteSpace(value) ? s_defaultOutputName : value); } + set { UpdateProperty(ref _outputName, string.IsNullOrWhiteSpace(value) ? DefaultOutputFileName : value); } } public static OptionsModel Load() { try { - if (File.Exists(s_optionsFilePath)) + if (File.Exists(OptionsFilePath)) { - var bytes = File.ReadAllBytes(s_optionsFilePath); + var bytes = File.ReadAllBytes(OptionsFilePath); return bytes.Deserialize(); } @@ -96,13 +96,13 @@ public bool Save() { try { - File.WriteAllBytes(s_optionsFilePath, this.Serialize()); + File.WriteAllBytes(OptionsFilePath, this.Serialize()); return true; } catch (IOException) { - Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnableToSaveFileFormat, s_optionsFilePath)); + Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnableToSaveFileFormat, OptionsFilePath)); return false; } diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatform.cs b/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatform.cs index 6bbecb534..77304540a 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatform.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatform.cs @@ -25,9 +25,7 @@ public TargetPlatform() public override bool Equals(object obj) { - var compared = obj as TargetPlatform; - - if (compared == null) + if (!(obj is TargetPlatform compared)) return false; return string.Equals(Name, compared.Name, StringComparison.Ordinal) @@ -44,14 +42,14 @@ public override int GetHashCode() if (Name != null) { - hash = hash * HashMultipler + Name.GetHashCode(); + hash = (hash * HashMultipler) + Name.GetHashCode(); } if (Versions != null) { foreach (var version in Versions) { - hash = hash * HashMultipler + version.GetHashCode(); + hash = (hash * HashMultipler) + version.GetHashCode(); } } diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs index 973d1d8dc..545a69448 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CodeDocumentNavigator.cs @@ -11,7 +11,7 @@ namespace ApiPortVS.SourceMapping { internal static class CodeDocumentNavigator { - private static Guid s_logicalViewGuid = VSConstants.LOGVIEWID.Code_guid; + private static Guid _logicalViewGuid = VSConstants.LOGVIEWID.Code_guid; public static void Navigate(object sender, EventArgs e) { @@ -44,7 +44,7 @@ public static void OpenDocumentTo(string documentPath, int line, int column) if (Package.GetGlobalService(typeof(VsTextManagerClass)) is IVsTextManager textManager && buffer != null) { - textManager.NavigateToLineAndColumn(buffer, ref s_logicalViewGuid, line, column, line, column); + textManager.NavigateToLineAndColumn(buffer, ref _logicalViewGuid, line, column, line, column); } } @@ -57,7 +57,7 @@ private static IVsWindowFrame GetFrameForDocument(string documentPath) { ErrorHandler.ThrowOnFailure(openDocument.OpenDocumentViaProject( documentPath, - ref s_logicalViewGuid, + ref _logicalViewGuid, out var serviceProvider, out var hierarchy, out var itemId, diff --git a/src/ApiPort/ApiPort.VisualStudio/ApiPort.VisualStudio.csproj b/src/ApiPort/ApiPort.VisualStudio/ApiPort.VisualStudio.csproj index bbc9f34b1..779165ceb 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ApiPort.VisualStudio.csproj +++ b/src/ApiPort/ApiPort.VisualStudio/ApiPort.VisualStudio.csproj @@ -94,7 +94,6 @@ - diff --git a/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs b/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs index 9647dea98..ba2813cd8 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs +++ b/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs @@ -23,16 +23,16 @@ namespace ApiPortVS [ProvideToolWindow(typeof(AnalysisOutputToolWindow))] public class ApiPortVSPackage : Package, IResultToolbar { - private static ServiceProvider s_serviceProvider; + private static ServiceProvider _serviceProvider; private readonly AssemblyRedirectResolver _assemblyResolver; - internal static IServiceProvider LocalServiceProvider { get { return s_serviceProvider; } } + internal static IServiceProvider LocalServiceProvider { get { return _serviceProvider; } } public ApiPortVSPackage() : base() { - s_serviceProvider = new ServiceProvider(this); - _assemblyResolver = s_serviceProvider.GetService(typeof(AssemblyRedirectResolver)) as AssemblyRedirectResolver; + _serviceProvider = new ServiceProvider(this); + _assemblyResolver = _serviceProvider.GetService(typeof(AssemblyRedirectResolver)) as AssemblyRedirectResolver; if (_assemblyResolver == default(AssemblyRedirectResolver)) { @@ -44,7 +44,7 @@ public ApiPortVSPackage() protected override void Dispose(bool disposing) { - s_serviceProvider.Dispose(); + _serviceProvider.Dispose(); AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; base.Dispose(disposing); @@ -69,17 +69,17 @@ protected override void Initialize() mcs.AddCommand(analyzeMenuOptionsItem); CommandID analyzeMenuToolbarCommandID = new CommandID(Guids.AnalyzeMenuItemCmdSet, (int)PkgCmdID.CmdIdAnalyzeToolbarMenuItem); - MenuCommand analyzeMenuToolbarItem = new MenuCommand(async (_, __) => await ShowToolbarAsync().ConfigureAwait(false), analyzeMenuToolbarCommandID); + MenuCommand analyzeMenuToolbarItem = new MenuCommand(async (_, e) => await ShowToolbarAsync().ConfigureAwait(false), analyzeMenuToolbarCommandID); mcs.AddCommand(analyzeMenuToolbarItem); // Add menu items for Project context menus CommandID projectContextMenuCmdId = new CommandID(Guids.ProjectContextMenuItemCmdSet, (int)PkgCmdID.CmdIdProjectContextMenuItem); - OleMenuCommand contextMenuItem = new OleMenuCommand(async (_, __) => await menuInitializer.AnalyzeSelectedProjectsAsync(false), projectContextMenuCmdId); + OleMenuCommand contextMenuItem = new OleMenuCommand(async (_, e) => await menuInitializer.AnalyzeSelectedProjectsAsync(false), projectContextMenuCmdId); contextMenuItem.BeforeQueryStatus += menuInitializer.ProjectContextMenuItemBeforeQueryStatus; mcs.AddCommand(contextMenuItem); CommandID projectContextMenuDependentsCmdId = new CommandID(Guids.ProjectContextMenuItemCmdSet, (int)PkgCmdID.CmdIdProjectContextDependentsMenuItem); - OleMenuCommand contextMenuDependentsItem = new OleMenuCommand(async (_, __) => await menuInitializer.AnalyzeSelectedProjectsAsync(true), projectContextMenuDependentsCmdId); + OleMenuCommand contextMenuDependentsItem = new OleMenuCommand(async (_, e) => await menuInitializer.AnalyzeSelectedProjectsAsync(true), projectContextMenuDependentsCmdId); contextMenuDependentsItem.BeforeQueryStatus += menuInitializer.ProjectContextMenuDependenciesItemBeforeQueryStatus; mcs.AddCommand(contextMenuDependentsItem); diff --git a/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs b/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs index ce478dc4b..decca7afa 100644 --- a/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs +++ b/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs @@ -83,13 +83,13 @@ public Assembly ResolveAssembly(string assemblyName, Assembly requestingAssembly } } - internal class AssemblyRedirect + internal readonly struct AssemblyRedirect { - public readonly string Name; + public string Name { get; } - public readonly string PublicKeyToken; + public string PublicKeyToken { get; } - public readonly Version TargetVersion; + public Version TargetVersion { get; } public AssemblyRedirect(string name, string version, string publicKeyToken) { diff --git a/src/ApiPort/ApiPort.VisualStudio/GlobalSuppressions.cs b/src/ApiPort/ApiPort.VisualStudio/GlobalSuppressions.cs deleted file mode 100644 index 83335b44b..000000000 --- a/src/ApiPort/ApiPort.VisualStudio/GlobalSuppressions.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -// This file is used by Code Analysis to maintain SuppressMessage -// attributes that are applied to this project. Project-level -// suppressions either have no target or are given a specific target -// and scoped to a namespace, type, member, etc. -// -// To add a suppression to this file, right-click the message in the -// Error List, point to "Suppress Message(s)", and click "In Project -// Suppression File". You do not need to add suppressions to this -// file manually. - -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")] diff --git a/src/ApiPort/ApiPort.VisualStudio/OutputWindowWriter.cs b/src/ApiPort/ApiPort.VisualStudio/OutputWindowWriter.cs index 95f224374..cc22244a6 100644 --- a/src/ApiPort/ApiPort.VisualStudio/OutputWindowWriter.cs +++ b/src/ApiPort/ApiPort.VisualStudio/OutputWindowWriter.cs @@ -40,7 +40,7 @@ public async Task ShowWindowAsync() try { - Window window = _dte.Windows.Item(Constants.vsWindowKindOutput); + Window window = _dte.Windows.Item(Constants.VsWindowKindOutput); window.Activate(); } catch (Exception) { } @@ -76,7 +76,7 @@ private static class Constants /// /// https://msdn.microsoft.com/en-us/library/envdte.constants.vswindowkindoutput.aspx?f=255&MSPPError=-2147217396 /// - public const string vsWindowKindOutput = "{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}"; + public const string VsWindowKindOutput = "{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}"; } } } diff --git a/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs b/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs index b52ef586a..d02ae1ac8 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs +++ b/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs @@ -30,7 +30,7 @@ internal sealed class ServiceProvider : IDisposable, IServiceProvider { private const string DefaultEndpoint = @"https://portability.dot.net/"; private static readonly DirectoryInfo AssemblyDirectory = new FileInfo(typeof(ServiceProvider).Assembly.Location).Directory; - private static Guid OutputWindowGuid = new Guid(0xe2fc797f, 0x1dd3, 0x476c, 0x89, 0x17, 0x86, 0xcd, 0x31, 0x33, 0xc4, 0x69); + private static Guid _outputWindowGuid = new Guid(0xe2fc797f, 0x1dd3, 0x476c, 0x89, 0x17, 0x86, 0xcd, 0x31, 0x33, 0xc4, 0x69); private readonly IContainer _container; @@ -173,14 +173,14 @@ private static void RegisterVisualStudioComponents(ContainerBuilder builder, Api { var outputWindow = provider.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow; - if (outputWindow.GetPane(ref OutputWindowGuid, out IVsOutputWindowPane windowPane) == S_OK) + if (outputWindow.GetPane(ref _outputWindowGuid, out IVsOutputWindowPane windowPane) == S_OK) { return windowPane; } - if (outputWindow.CreatePane(ref OutputWindowGuid, LocalizedStrings.PortabilityOutputTitle, 1, 0) == S_OK) + if (outputWindow.CreatePane(ref _outputWindowGuid, LocalizedStrings.PortabilityOutputTitle, 1, 0) == S_OK) { - if (outputWindow.GetPane(ref OutputWindowGuid, out windowPane) == S_OK) + if (outputWindow.GetPane(ref _outputWindowGuid, out windowPane) == S_OK) { return windowPane; } diff --git a/src/ApiPort/ApiPort/FileOutputApiPortService.cs b/src/ApiPort/ApiPort/FileOutputApiPortService.cs index 748f1035f..71bfadfe6 100644 --- a/src/ApiPort/ApiPort/FileOutputApiPortService.cs +++ b/src/ApiPort/ApiPort/FileOutputApiPortService.cs @@ -16,9 +16,9 @@ namespace ApiPort /// internal class FileOutputApiPortService : IApiPortService { - private static readonly IReadOnlyCollection s_emptySearchResults = new ApiDefinition[] { }; - private static readonly IReadOnlyCollection s_emptyQueryDocIds = new ApiInformation[] { }; - private static readonly IEnumerable s_formats = new[] + private static readonly IReadOnlyCollection EmptySearchResults = new ApiDefinition[] { }; + private static readonly IReadOnlyCollection EmptyQueryDocIds = new ApiInformation[] { }; + private static readonly IEnumerable Formats = new[] { new ResultFormatInformation { @@ -60,7 +60,7 @@ public Task> GetApiInformationAsync(string docId public Task>> GetResultFormatsAsync() { - var response = ServiceResponse.Create(s_formats); + var response = ServiceResponse.Create(Formats); return Task.FromResult(response); } @@ -68,7 +68,7 @@ public Task>> GetResultForm public Task> GetDefaultResultFormatAsync() { // s_formats contains one element - var response = ServiceResponse.Create(s_formats.First()); + var response = ServiceResponse.Create(Formats.First()); return Task.FromResult(response); } @@ -84,15 +84,15 @@ public Task>> GetTargetsAsync() public Task>> QueryDocIdsAsync(IEnumerable docIds) { _progress.ReportIssue(LocalizedStrings.FileOutputServiceNotSupported); - var response = ServiceResponse.Create(s_emptyQueryDocIds); + var response = ServiceResponse.Create(EmptyQueryDocIds); return Task.FromResult(response); } - public Task>> SearchFxApiAsync(string query, int? top = default(int?)) + public Task>> SearchFxApiAsync(string query, int? top = default) { _progress.ReportIssue(LocalizedStrings.FileOutputServiceNotSupported); - var response = ServiceResponse.Create(s_emptySearchResults); + var response = ServiceResponse.Create(EmptySearchResults); return Task.FromResult(response); } @@ -105,11 +105,11 @@ public Task> SendAnalysisAsync(AnalyzeRequest a } /// - /// Returns the analysis as . Input is ignored. + /// Returns the analysis as . Input is ignored. /// public Task>> SendAnalysisAsync(AnalyzeRequest a, IEnumerable formats) { - var result = s_formats.Select(f => new ReportingResultWithFormat + var result = Formats.Select(f => new ReportingResultWithFormat { Data = SendAnalysisAsync(a, f.DisplayName), Format = f.DisplayName diff --git a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/CciDependencyFinder.cs b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/CciDependencyFinder.cs index 1c5aa3f8d..2b7946072 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/CciDependencyFinder.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/CciDependencyFinder.cs @@ -11,11 +11,11 @@ namespace Microsoft.Fx.Portability.Analyzer { public class CciDependencyFinder : IDependencyFinder { - public IDependencyInfo FindDependencies(IEnumerable inputAssemblies, IProgressReporter _progressReport) + public IDependencyInfo FindDependencies(IEnumerable inputAssemblies, IProgressReporter progressReport) { - var inputAssemblyPaths = inputAssemblies.Where(f => FilterValidFiles(f, _progressReport)).Select(i => i.Name).ToList(); + var inputAssemblyPaths = inputAssemblies.Where(f => FilterValidFiles(f, progressReport)).Select(i => i.Name).ToList(); - using (var task = _progressReport.StartTask(LocalizedStrings.DetectingAssemblyReferences, inputAssemblyPaths.Count)) + using (var task = progressReport.StartTask(LocalizedStrings.DetectingAssemblyReferences, inputAssemblyPaths.Count)) { try { @@ -29,14 +29,14 @@ public IDependencyInfo FindDependencies(IEnumerable inputAssembli } } - private static bool FilterValidFiles(IAssemblyFile file, IProgressReporter _progressReport) + private static bool FilterValidFiles(IAssemblyFile file, IProgressReporter progressReport) { if (file.Exists) { return true; } - _progressReport.ReportIssue(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnknownFile, file.Name)); + progressReport.ReportIssue(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnknownFile, file.Name)); return false; } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs index 5c99d8d56..1c9e802fb 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs @@ -320,7 +320,7 @@ private string GenerateMemberDocId() private static bool CalculateGenericArgsOffset(string displayName, int pos, out int numGenericArgs, out int offsetStringAfterGenericMarker) { - Debug.Assert(displayName[pos] == '`'); + Debug.Assert(displayName[pos] == '`', $"Name should contain ` but contains {displayName[pos]}"); offsetStringAfterGenericMarker = ++pos; diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs index 6d991e661..68527077f 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs @@ -175,7 +175,8 @@ public MemberMetadataInfo GetFullName(TypeReference reference, TypeReference? ch // equivalent if my understanding is correct. I don't know // if it will resolve ExportedTypes from the same syntax // however. - Debug.Assert(scope.IsNil || scope == Handle.ModuleDefinition); + Debug.Assert(scope.IsNil || scope == Handle.ModuleDefinition, + "This is a rare case. Add this to verify an unusual situation."); return name; } } @@ -258,7 +259,7 @@ public MemberMetadataInfo GetPrimitiveType(PrimitiveTypeCode typeCode) break; default: - Debug.Assert(false); + Debug.Assert(false, $"Not supported typecode [{typeCode}]."); throw new ArgumentOutOfRangeException(nameof(typeCode)); } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyFinder.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyFinder.cs index d7f6a2e31..63f0bd79b 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyFinder.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyFinder.cs @@ -18,13 +18,13 @@ public ReflectionMetadataDependencyFinder(IDependencyFilter assemblyFilter, Syst _objectFinder = objectFinder; } - public IDependencyInfo FindDependencies(IEnumerable files, IProgressReporter _progressReporter) + public IDependencyInfo FindDependencies(IEnumerable files, IProgressReporter progressReporter) { - using (var task = _progressReporter.StartTask(LocalizedStrings.DetectingAssemblyReferences)) + using (var task = progressReporter.StartTask(LocalizedStrings.DetectingAssemblyReferences)) { try { - return ReflectionMetadataDependencyInfo.ComputeDependencies(files, _assemblyFilter, _progressReporter, _objectFinder); + return ReflectionMetadataDependencyInfo.ComputeDependencies(files, _assemblyFilter, progressReporter, _objectFinder); } catch (Exception) { diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs index 9ba916aa0..2f320985b 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/SystemObjectFinder.cs @@ -11,7 +11,7 @@ namespace Microsoft.Fx.Portability.Analyzer { public class SystemObjectFinder { - private static readonly HashSet s_systemObjectAssemblies = new HashSet(StringComparer.Ordinal) + private static readonly HashSet SystemObjectAssemblies = new HashSet(StringComparer.Ordinal) { "mscorlib", "netstandard", @@ -31,7 +31,7 @@ public SystemObjectFinder(IDependencyFilter assemblyFilter) /// public bool TryGetSystemRuntimeAssemblyInformation(MetadataReader reader, out AssemblyReferenceInformation assemblyReference) { - if (reader.TryGetCurrentAssemblyName(out var name) && s_systemObjectAssemblies.Contains(name)) + if (reader.TryGetCurrentAssemblyName(out var name) && SystemObjectAssemblies.Contains(name)) { assemblyReference = reader.FormatAssemblyInfo(); return true; @@ -44,7 +44,7 @@ public bool TryGetSystemRuntimeAssemblyInformation(MetadataReader reader, out As return reader.FormatAssemblyInfo(assembly); }) .Where(_assemblyFilter.IsFrameworkAssembly) - .Where(assembly => s_systemObjectAssemblies.Contains(assembly.Name)) + .Where(assembly => SystemObjectAssemblies.Contains(assembly.Name)) .OrderByDescending(assembly => assembly.Version); var matchingAssembly = microsoftAssemblies.FirstOrDefault(); diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs index 56811ec09..3787f2c3c 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs @@ -307,7 +307,7 @@ private void GenerateDetailsPage(Worksheet detailsPage, ReportingResult analysis detailsPage.AddColumnWidth(columnWidths); } - private void GenerateBreakingChangesPage(Worksheet worksheet, IEnumerable _breakingChanges) + private void GenerateBreakingChangesPage(Worksheet worksheet, IEnumerable breakingChanges) { var row = 1; @@ -332,7 +332,7 @@ private void GenerateBreakingChangesPage(Worksheet worksheet, IEnumerable(); - if (_sheets == null) + var sheets = spreadsheet.WorkbookPart.Workbook.GetFirstChild(); + if (sheets == null) { - _sheets = new Sheets(); - spreadsheet.WorkbookPart.Workbook.AppendChild(_sheets); + sheets = new Sheets(); + spreadsheet.WorkbookPart.Workbook.AppendChild(sheets); } var worksheetPart = spreadsheet.WorkbookPart.AddNewPart(); @@ -34,10 +34,10 @@ public static Worksheet AddWorksheet(this SpreadsheetDocument spreadsheet, strin worksheetPart.Worksheet.Save(); // create the worksheet to workbook relation - _sheets.AppendChild(new Sheet() + sheets.AppendChild(new Sheet() { Id = spreadsheet.WorkbookPart.GetIdOfPart(worksheetPart), - SheetId = new DocumentFormat.OpenXml.UInt32Value((uint)_sheets.Count() + 1), + SheetId = new DocumentFormat.OpenXml.UInt32Value((uint)sheets.Count() + 1), Name = name }); @@ -218,7 +218,7 @@ private static string GetColumnName(int index) var sb = new StringBuilder(); if (index >= Alphabet.Length) - sb.Append(Alphabet[index / Alphabet.Length - 1]); + sb.Append(Alphabet[(index / Alphabet.Length) - 1]); sb.Append(Alphabet[index % Alphabet.Length]); @@ -263,7 +263,7 @@ public static void AddColumnWidth(this Worksheet ws, IEnumerable columnW } } - static Cell CreateTextCell(string text) + public static Cell CreateTextCell(string text) { var cell = new Cell { @@ -280,7 +280,7 @@ static Cell CreateTextCell(string text) return cell; } - static Cell CreateNumberCell(string value) + public static Cell CreateNumberCell(string value) { return new Cell { diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs index 1e1af971b..1f7250b24 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Html/HtmlReportWriter.cs @@ -19,7 +19,7 @@ namespace Microsoft.Fx.Portability.Reports { public class HtmlReportWriter : IReportWriter { - private static readonly IRazorEngineService s_razorService = CreateService(); + private static readonly IRazorEngineService RazorService = CreateService(); private readonly ITargetMapper _targetMapper; private static readonly ResultFormatInformation _formatInformation = new ResultFormatInformation @@ -44,7 +44,7 @@ public void WriteStream(Stream stream, AnalyzeResponse response) { var reportObject = new RazorHtmlObject(response, _targetMapper); var mainTemplate = Resolve(ReportTemplateName); - var razor = s_razorService.RunCompile(mainTemplate, ReportTemplateName, typeof(RazorHtmlObject), reportObject); + var razor = RazorService.RunCompile(mainTemplate, ReportTemplateName, typeof(RazorHtmlObject), reportObject); writer.Write(razor); } @@ -96,7 +96,7 @@ public IEncodedString Raw(string rawString) public IEncodedString Partial(string name) { var template = Resolve(name); - var razor = s_razorService.RunCompile(template, name); + var razor = RazorService.RunCompile(template, name); return Raw(razor); } @@ -104,7 +104,7 @@ public IEncodedString Partial(string name) public IEncodedString Partial(string name, T model) { var template = Resolve(name); - var razor = s_razorService.RunCompile(template, name, typeof(T), model); + var razor = RazorService.RunCompile(template, name, typeof(T), model); return Raw(razor); } diff --git a/src/lib/Microsoft.Fx.Portability/AliasMappedToMultipleNamesException.cs b/src/lib/Microsoft.Fx.Portability/AliasMappedToMultipleNamesException.cs index 128b83e04..a7cfe90e7 100644 --- a/src/lib/Microsoft.Fx.Portability/AliasMappedToMultipleNamesException.cs +++ b/src/lib/Microsoft.Fx.Portability/AliasMappedToMultipleNamesException.cs @@ -9,11 +9,11 @@ namespace Microsoft.Fx.Portability { public class AliasMappedToMultipleNamesException : PortabilityAnalyzerException { - private static readonly string s_listSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator + " "; + private static readonly string ListSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator + " "; private static string GenerateMessage(IEnumerable invalidNames) { - return string.Format(CultureInfo.CurrentCulture, LocalizedStrings.AliasMappedToMultipleNamesInvalidAliases, string.Join(s_listSeparator, invalidNames)); + return string.Format(CultureInfo.CurrentCulture, LocalizedStrings.AliasMappedToMultipleNamesInvalidAliases, string.Join(ListSeparator, invalidNames)); } public AliasMappedToMultipleNamesException(IEnumerable invalidNames) diff --git a/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs b/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs index 56eebb2ff..e52966f85 100644 --- a/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs +++ b/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs @@ -350,7 +350,7 @@ private static bool IsSupportedOnTarget(IApiCatalogLookup catalog, string member private class MemberInfoBreakingChangeComparer : IEqualityComparer> { - public static IEqualityComparer> Instance = new MemberInfoBreakingChangeComparer(); + public static readonly IEqualityComparer> Instance = new MemberInfoBreakingChangeComparer(); public bool Equals(Tuple x, Tuple y) { diff --git a/src/lib/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs b/src/lib/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs index c81434b3a..37a73e2f2 100644 --- a/src/lib/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs +++ b/src/lib/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs @@ -14,7 +14,7 @@ public class DotNetFrameworkFilter : IDependencyFilter /// These keys are a collection of public key tokens derived from all the reference assemblies in /// "%ProgramFiles%\Reference Assemblies\Microsoft" on a Windows 10 machine with VS 2015 installed /// - private static readonly ICollection s_microsoftKeys = new HashSet(new[] + private static readonly ICollection MicrosoftKeys = new HashSet(new[] { "b77a5c561934e089", // ECMA "b03f5f7f11d50a3a", // DEVDIV @@ -25,7 +25,7 @@ public class DotNetFrameworkFilter : IDependencyFilter "cc7b13ffcd2ddd51" // NetStandard }, StringComparer.OrdinalIgnoreCase); - private static readonly IEnumerable s_frameworkAssemblyNamePrefixes = new[] + private static readonly IEnumerable FrameworkAssemblyNamePrefixes = new[] { "System.", "Microsoft.AspNet.", @@ -45,12 +45,12 @@ public bool IsFrameworkAssembly(AssemblyReferenceInformation assembly) return true; } - if (s_microsoftKeys.Contains(assembly.PublicKeyToken)) + if (MicrosoftKeys.Contains(assembly.PublicKeyToken)) { return true; } - if (s_frameworkAssemblyNamePrefixes.Any(p => assembly.Name.StartsWith(p, StringComparison.OrdinalIgnoreCase))) + if (FrameworkAssemblyNamePrefixes.Any(p => assembly.Name.StartsWith(p, StringComparison.OrdinalIgnoreCase))) { return true; } diff --git a/src/lib/Microsoft.Fx.Portability/BreakingChange.cs b/src/lib/Microsoft.Fx.Portability/BreakingChange.cs index a9e153c8a..02547ec4b 100644 --- a/src/lib/Microsoft.Fx.Portability/BreakingChange.cs +++ b/src/lib/Microsoft.Fx.Portability/BreakingChange.cs @@ -73,7 +73,7 @@ public bool IsRetargeting public BreakingChangeImpact ImpactScope { get; set; } - public IList Categories; + public IList Categories { get; set; } public int CompareTo(BreakingChange other) { diff --git a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs index 266caa234..263480693 100644 --- a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs +++ b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs @@ -15,7 +15,7 @@ public static class BreakingChangeParser /// /// Items that can show up in the breaking change 'Affected APIs' section that should be ignored /// - private static readonly ICollection s_ignoredApis = new HashSet(new[] + private static readonly ICollection IgnoredApis = new HashSet(new[] { "Not detectable via API analysis", "Investigate applicable APIs" @@ -271,7 +271,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.ApplicableApis = new List(); } - if (!s_ignoredApis.Contains(api)) + if (!IgnoredApis.Contains(api)) { currentBreak.ApplicableApis.Add(api); } diff --git a/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs b/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs index 5eaeb92dc..7bd22ef60 100644 --- a/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs +++ b/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs @@ -167,7 +167,8 @@ private async Task>> Call var boundary = contentType.Parameters.FirstOrDefault(p => string.Equals("boundary", p.Name, StringComparison.OrdinalIgnoreCase))?.Value .Trim('\"'); - Debug.Assert(boundary != null); + Debug.Assert(boundary != null, + $"boundary not parsed from parameters: {string.Join(",", contentType.Parameters.Select(x => x.Name))}"); using (var stream = await response.Content.ReadAsStreamAsync()) { diff --git a/src/lib/Microsoft.Fx.Portability/DataExtensions.cs b/src/lib/Microsoft.Fx.Portability/DataExtensions.cs index ad3c655da..658c3bed7 100644 --- a/src/lib/Microsoft.Fx.Portability/DataExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability/DataExtensions.cs @@ -16,7 +16,7 @@ namespace Microsoft.Fx.Portability public static class DataExtensions { private const int DefaultBufferSize = 1024; - private static readonly Encoding s_defaultEncoding = Encoding.UTF8; + private static readonly Encoding DefaultEncoding = Encoding.UTF8; public static JsonSerializerSettings JsonSettings { get; } = new JsonSerializerSettings { @@ -76,7 +76,7 @@ public static byte[] SerializeAndCompress(this T data) /// true to leave the stream open; false otherwise public static void Serialize(this T data, Stream outputStream, bool leaveOpen) { - using (var writer = new StreamWriter(outputStream, s_defaultEncoding, DefaultBufferSize, leaveOpen)) + using (var writer = new StreamWriter(outputStream, DefaultEncoding, DefaultBufferSize, leaveOpen)) { Serializer.Serialize(writer, data); } @@ -119,7 +119,7 @@ public static byte[] Compress(this byte[] data) /// public static async Task CompressAsync(this Stream inputStream, Stream outputStream, bool leaveOpen) { - using (var reader = new BinaryReader(inputStream, s_defaultEncoding, leaveOpen)) + using (var reader = new BinaryReader(inputStream, DefaultEncoding, leaveOpen)) using (var compressionStream = new GZipStream(outputStream, CompressionMode.Compress, leaveOpen)) { reader.BaseStream.Seek(0, SeekOrigin.Begin); diff --git a/src/lib/Microsoft.Fx.Portability/IAnalysisEngine.cs b/src/lib/Microsoft.Fx.Portability/IAnalysisEngine.cs index d40956512..6f3fa7ca2 100644 --- a/src/lib/Microsoft.Fx.Portability/IAnalysisEngine.cs +++ b/src/lib/Microsoft.Fx.Portability/IAnalysisEngine.cs @@ -32,7 +32,7 @@ IEnumerable FindBreakingChanges( IEnumerable assembliesToIgnore, IEnumerable breakingChangesToSuppress, ICollection userAssemblies, - bool ShowRetargettingIssues = false); + bool showRetargettingIssues = false); IEnumerable GetNuGetPackagesInfoFromAssembly(IEnumerable assemblies, IEnumerable targets); diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyReferenceInformation.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyReferenceInformation.cs index f82e2e9d2..f1504fcb3 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyReferenceInformation.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyReferenceInformation.cs @@ -9,7 +9,7 @@ namespace Microsoft.Fx.Portability.ObjectModel { public class AssemblyReferenceInformation { - private static readonly StringComparer s_comparer = StringComparer.OrdinalIgnoreCase; + private static readonly StringComparer DefaultComparer = StringComparer.OrdinalIgnoreCase; private readonly string _string; @@ -33,8 +33,8 @@ public AssemblyReferenceInformation(string name, Version version, string culture public override string ToString() => _string; - public override bool Equals(object obj) => s_comparer.Equals(_string, (obj as AssemblyReferenceInformation)?._string); + public override bool Equals(object obj) => DefaultComparer.Equals(_string, (obj as AssemblyReferenceInformation)?._string); - public override int GetHashCode() => s_comparer.GetHashCode(_string); + public override int GetHashCode() => DefaultComparer.GetHashCode(_string); } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/NuGetPackageInfo.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/NuGetPackageInfo.cs index b2c2843d8..aee879975 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/NuGetPackageInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/NuGetPackageInfo.cs @@ -56,8 +56,8 @@ public override int GetHashCode() if (!_hashComputed) { var hash = 17; - hash = hash * 23 + (AssemblyInfo ?? string.Empty).GetHashCode(); - hash = hash * 23 + (PackageId ?? string.Empty).GetHashCode(); + hash = (hash * 23) + (AssemblyInfo ?? string.Empty).GetHashCode(); + hash = (hash * 23) + (PackageId ?? string.Empty).GetHashCode(); _hashCode = hash; _hashComputed = true; } @@ -79,8 +79,8 @@ public bool Equals(KeyValuePair x, KeyValuePair kvp) { var hash = 17; - hash = hash * 23 + kvp.Key.GetHashCode(); - hash = hash * 23 + (kvp.Value ?? string.Empty).GetHashCode(); + hash = (hash * 23) + kvp.Key.GetHashCode(); + hash = (hash * 23) + (kvp.Value ?? string.Empty).GetHashCode(); return hash; } } diff --git a/src/lib/Microsoft.Fx.Portability/Proxy/ProxyAuthenticationHandler.cs b/src/lib/Microsoft.Fx.Portability/Proxy/ProxyAuthenticationHandler.cs index 4b8f9f17d..76bf680fe 100644 --- a/src/lib/Microsoft.Fx.Portability/Proxy/ProxyAuthenticationHandler.cs +++ b/src/lib/Microsoft.Fx.Portability/Proxy/ProxyAuthenticationHandler.cs @@ -35,9 +35,9 @@ public ProxyAuthenticationHandler(HttpClientHandler httpClientHandler, IProxyPro protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - int _attempts = 0; + int attempts = 0; - while (_attempts < MaxAttempts) + while (attempts < MaxAttempts) { try { @@ -55,7 +55,7 @@ protected override async Task SendAsync(HttpRequestMessage } } - _attempts++; + attempts++; } throw new PortabilityAnalyzerException(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.UnknownErrorCodeMessage, HttpStatusCode.BadRequest)); diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs index a377caca4..a7b4facae 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs @@ -12,7 +12,6 @@ namespace Microsoft.Fx.Portability.Reporting.ObjectModel public class MissingTypeInfo : MissingInfo { private readonly HashSet _usedInAssemblies; - private bool _isMissing; public int UsageCount { get { return _usedInAssemblies.Count; } } @@ -22,9 +21,9 @@ public class MissingTypeInfo : MissingInfo public IEnumerable TargetVersionStatus { get; set; } - public bool IsMissing { get { return _isMissing; } } + public bool IsMissing { get; private set; } - public HashSet MissingMembers; + public HashSet MissingMembers { get; } public string TypeName { get; set; } @@ -43,7 +42,7 @@ public void AddMissingMember(MissingMemberInfo mmi, AssemblyInfo sourceAssembly) public void MarkAsMissing() { - _isMissing = true; + IsMissing = true; } public void IncrementUsage(AssemblyInfo sourceAssembly) @@ -79,9 +78,8 @@ public override int GetHashCode() public override bool Equals(object obj) { - MissingTypeInfo other = obj as MissingTypeInfo; - - return other != null && StringComparer.Ordinal.Equals(other.TypeName, TypeName); + return obj is MissingTypeInfo other + && StringComparer.Ordinal.Equals(other.TypeName, TypeName); } } } diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs index 83137ab7a..c3b460895 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/ManagedMetadataReaderTests.cs @@ -11,25 +11,25 @@ namespace Microsoft.Fx.Portability.Cci.Tests { public class ManagedMetadataReaderTests { - private static readonly string s_emptyProjectPath = TestAssembly.EmptyProject; - private static readonly string s_withGenericsAndReferencePath = TestAssembly.WithGenericsAndReference; + private static readonly string EmptyProjectPath = TestAssembly.EmptyProject; + private static readonly string WithGenericsAndReferencePath = TestAssembly.WithGenericsAndReference; [Fact] public static void EmptyProject() { - CompareFinders(s_emptyProjectPath); + CompareFinders(EmptyProjectPath); } [Fact] public static void WithGenericsAndReference() { - CompareFinders(s_withGenericsAndReferencePath); + CompareFinders(WithGenericsAndReferencePath); } [Fact] public static void WithGenericsAndReferenceAndEmptyProject() { - CompareFinders(s_withGenericsAndReferencePath, s_emptyProjectPath); + CompareFinders(WithGenericsAndReferencePath, EmptyProjectPath); } private static void CompareFinders(params string[] paths) diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs index f71d573dc..e3c262a41 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs @@ -17,7 +17,7 @@ namespace Microsoft.Fx.Portability.Cci.Tests internal class TestAssembly { private const string TFM = @"[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")]"; - private static readonly string s_mscorlib = typeof(object).GetTypeInfo().Assembly.Location; + private static readonly string Mscorlib = typeof(object).GetTypeInfo().Assembly.Location; private readonly string _path; private TestAssembly(string assemblyName, string text, IEnumerable referencePaths) @@ -56,7 +56,7 @@ public static string EmptyProject get { var text = GetText("EmptyProject.cs"); - return new TestAssembly("EmptyProject", text, new[] { s_mscorlib }).Path; + return new TestAssembly("EmptyProject", text, new[] { Mscorlib }).Path; } } @@ -65,7 +65,7 @@ public static string WithGenericsAndReference get { var text = GetText("WithGenericsAndReference.cs"); - return new TestAssembly("WithGenericsAndReference", text, new[] { s_mscorlib, EmptyProject }).Path; + return new TestAssembly("WithGenericsAndReference", text, new[] { Mscorlib, EmptyProject }).Path; } } diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs index f29803fb6..36506d9f3 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs @@ -18,7 +18,7 @@ namespace Microsoft.Fx.Portability.MetadataReader.Tests { internal static class TestAssembly { - private static readonly Assembly s_assembly = typeof(TestAssembly).GetTypeInfo().Assembly; + private static readonly Assembly Assembly = typeof(TestAssembly).GetTypeInfo().Assembly; public static IAssemblyFile CreateFromIL(string il, string name, ITestOutputHelper output) { @@ -63,7 +63,7 @@ public StringAssemblyFile(string name, string contents) private class CSharpCompileAssemblyFile : ResourceStreamAssemblyFile { private const string TFM = @"[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")]"; - private static readonly IEnumerable s_references = new[] { typeof(object).GetTypeInfo().Assembly.Location, typeof(Uri).GetTypeInfo().Assembly.Location, typeof(Console).GetTypeInfo().Assembly.Location } + private static readonly IEnumerable References = new[] { typeof(object).GetTypeInfo().Assembly.Location, typeof(Uri).GetTypeInfo().Assembly.Location, typeof(Console).GetTypeInfo().Assembly.Location } .Distinct() .Select(r => MetadataReference.CreateFromFile(r)) .ToList(); @@ -88,7 +88,7 @@ public override Stream OpenRead() var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: _allowUnsafe); var references = _additionalReferences .Select(x => MetadataReference.CreateFromFile(x)) - .Concat(s_references); + .Concat(References); var compilation = CSharpCompilation.Create(assemblyName, new[] { tree, tfm }, references, options); @@ -134,7 +134,7 @@ public ResourceStreamAssemblyFile(string fileName, ITestOutputHelper output) public virtual Stream OpenRead() { - var names = s_assembly.GetManifestResourceNames(); + var names = Assembly.GetManifestResourceNames(); var name = names.Single(n => n.EndsWith(Name, StringComparison.Ordinal)); if (name == null) @@ -149,13 +149,13 @@ public virtual Stream OpenRead() Assert.NotNull(name); - return s_assembly.GetManifestResourceStream(name); + return Assembly.GetManifestResourceStream(name); } } private class ILStreamAssemblyFile : IAssemblyFile { - private static readonly string s_ilAsmPath = Path.Combine(Path.GetDirectoryName(s_assembly.Location), "ilasm.exe"); + private static readonly string ILAssemblyPath = Path.Combine(Path.GetDirectoryName(Assembly.Location), "ilasm.exe"); private readonly IAssemblyFile _other; private readonly ITestOutputHelper _output; @@ -174,7 +174,7 @@ public ILStreamAssemblyFile(IAssemblyFile other, ITestOutputHelper output) public Stream OpenRead() { - if (!File.Exists(s_ilAsmPath)) + if (!File.Exists(ILAssemblyPath)) { throw new FileNotFoundException("Could not find ilasm"); } @@ -190,7 +190,7 @@ public Stream OpenRead() var psi = new ProcessStartInfo { Arguments = $"{ilPath} /dll", - FileName = s_ilAsmPath, + FileName = ILAssemblyPath, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false diff --git a/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs b/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs index 16b63598a..71be295ba 100644 --- a/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Offline.Tests/OffLineApiPortServiceTests.cs @@ -21,7 +21,7 @@ public class OffLineApiPortServiceTests private const string ParamText = "(int param1, EventArgs[] args)"; private const int MaxDocIdSetCount = 3; - private readonly OfflineApiPortService _OfflineApiPortService = new OfflineApiPortService( + private readonly OfflineApiPortService _offlineApiPortService = new OfflineApiPortService( CreateApiCatalogLookup(), CreateRequestAnalyzer(), CreateTargetMapper(), @@ -32,7 +32,7 @@ public class OffLineApiPortServiceTests [Fact] public async Task QueryDocIdsWithNullThrowsArgumentNullException() { - await Assert.ThrowsAsync(async () => await _OfflineApiPortService.QueryDocIdsAsync(null)); + await Assert.ThrowsAsync(async () => await _offlineApiPortService.QueryDocIdsAsync(null)); } [Fact] @@ -40,7 +40,7 @@ public async Task QueryDocIdsWithEmptyListOfValidIds() { var expectedDocIds = new List(); - var result = await _OfflineApiPortService.QueryDocIdsAsync(expectedDocIds); + var result = await _offlineApiPortService.QueryDocIdsAsync(expectedDocIds); Assert.Empty(result.Response); } @@ -56,7 +56,7 @@ public async Task QueryDocIdsWithAllValidIds() $"M:{ValidDocId}{ParamText}" }; - var result = await _OfflineApiPortService.QueryDocIdsAsync(expectedDocIds); + var result = await _offlineApiPortService.QueryDocIdsAsync(expectedDocIds); Assert.Equal(expectedDocIds.Count, result.Response.Count); Assert.Empty(expectedDocIds.Except(result.Response.Select(r => r.Definition.DocId))); } @@ -70,7 +70,7 @@ public async Task QueryDocIdsWithParameterDocIds() $"T:{ValidDocId}0", }; - var result = await _OfflineApiPortService.QueryDocIdsAsync(expectedDocIds); + var result = await _offlineApiPortService.QueryDocIdsAsync(expectedDocIds); Assert.Equal(expectedDocIds.Count, result.Response.Count); Assert.Empty(expectedDocIds.Except(result.Response.Select(r => r.Definition.DocId))); } @@ -85,7 +85,7 @@ public async Task QueryDocIdsWithNoValidIds() $"{InvalidDocId}{MaxDocIdSetCount + 3}" }; - var result = await _OfflineApiPortService.QueryDocIdsAsync(expectedDocIds); + var result = await _offlineApiPortService.QueryDocIdsAsync(expectedDocIds); Assert.Empty(result.Response); } @@ -109,7 +109,7 @@ public async Task QueryDocIdsWithSomeValidAndNonValidIds() $"P:{ValidDocId}0" }; - var result = await _OfflineApiPortService.QueryDocIdsAsync(docIdsToPass); + var result = await _offlineApiPortService.QueryDocIdsAsync(docIdsToPass); Assert.Equal(expectedDocIds.Count, result.Response.Count); Assert.Empty(expectedDocIds.Except(result.Response.Select(d => d.Definition.DocId))); } @@ -135,7 +135,7 @@ public async Task QueryDocIdsWithOneItemEmptyString() $"P:{ValidDocId}1" }; - var result = await _OfflineApiPortService.QueryDocIdsAsync(docIdsToPass); + var result = await _offlineApiPortService.QueryDocIdsAsync(docIdsToPass); Assert.Equal(expectedDocIds.Count, result.Response.Count); Assert.Empty(expectedDocIds.Except(result.Response.Select(d => d.Definition.DocId))); } @@ -150,7 +150,7 @@ public async Task QueryDocIdsWithDifferentDocIDCassingAreInvalid() $"P:{ValidDocId}0" }; - var result = await _OfflineApiPortService.QueryDocIdsAsync(expectedDocIds); + var result = await _offlineApiPortService.QueryDocIdsAsync(expectedDocIds); Assert.Equal(1, result.Response.Count); Assert.Equal($"P:{ValidDocId}0", result.Response.First().Definition.DocId); } @@ -178,7 +178,7 @@ public async Task QueryDocIdsWithSomeDuplicateValidIds() $"P:{ValidDocId}1", }; - var result = await _OfflineApiPortService.QueryDocIdsAsync(docIdsToPass); + var result = await _offlineApiPortService.QueryDocIdsAsync(docIdsToPass); Assert.Equal(expectedDocIds.Count, result.Response.Count); Assert.Empty(expectedDocIds.Except(result.Response.Select(r => r.Definition.DocId))); } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs index fd92e7362..62540b043 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/Analysis/AnalysisEngineTests.cs @@ -21,7 +21,7 @@ public class AnalysisEngineTests #region FindUnreferencedAssemblies - private static List s_unreferencedAssemblies = new List() + private static readonly List UnreferencedAssemblies = new List() { "Microsoft.CSharp, Version=4.0.0.0, PublicKeyToken=b03f5f7f11d50a3a", "MyAssembly" @@ -42,7 +42,7 @@ public static void FindUnreferencedAssemblies_SpecifiedAssembliesNull() var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); - var result = engine.FindUnreferencedAssemblies(s_unreferencedAssemblies, null).ToList(); + var result = engine.FindUnreferencedAssemblies(UnreferencedAssemblies, null).ToList(); Assert.NotNull(result); } @@ -54,8 +54,8 @@ public static void FindUnreferencedAssemblies_NoUnreferencedAssemblies() var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); - var specifiedUserAssemblies = s_unreferencedAssemblies.Select(ua => new AssemblyInfo() { AssemblyIdentity = ua, FileVersion = "0.0.0.0" }).ToList(); - var unreferencedAssms = engine.FindUnreferencedAssemblies(s_unreferencedAssemblies, specifiedUserAssemblies).ToList(); + var specifiedUserAssemblies = UnreferencedAssemblies.Select(ua => new AssemblyInfo() { AssemblyIdentity = ua, FileVersion = "0.0.0.0" }).ToList(); + var unreferencedAssms = engine.FindUnreferencedAssemblies(UnreferencedAssemblies, specifiedUserAssemblies).ToList(); // We don't expect to have any unreferenced assemblies. Assert.Empty(unreferencedAssms); @@ -65,13 +65,13 @@ public static void FindUnreferencedAssemblies_NoUnreferencedAssemblies() public static void FindUnreferencedAssemblies_UnreferencedAssemblies_1() { var catalog = Substitute.For(); - catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(s_unreferencedAssemblies[0])).Returns(true); + catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(UnreferencedAssemblies[0])).Returns(true); var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); var specifiedUserAssemblies = new[] { new AssemblyInfo { FileVersion = string.Empty, AssemblyIdentity = "MyAssembly" } }; - var unreferencedAssms = engine.FindUnreferencedAssemblies(s_unreferencedAssemblies, specifiedUserAssemblies).ToList(); + var unreferencedAssms = engine.FindUnreferencedAssemblies(UnreferencedAssemblies, specifiedUserAssemblies).ToList(); // 0 missing assembly since Microsoft.CSharp is a FX assembly and we specified MyAssembly Assert.Empty(unreferencedAssms); @@ -81,12 +81,12 @@ public static void FindUnreferencedAssemblies_UnreferencedAssemblies_1() public static void FindUnreferencedAssemblies_UnreferencedAssemblies_2() { var catalog = Substitute.For(); - catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(s_unreferencedAssemblies[0])).Returns(true); + catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(UnreferencedAssemblies[0])).Returns(true); var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); - var unreferencedAssms = engine.FindUnreferencedAssemblies(s_unreferencedAssemblies, Enumerable.Empty()).ToList(); + var unreferencedAssms = engine.FindUnreferencedAssemblies(UnreferencedAssemblies, Enumerable.Empty()).ToList(); // 1 missing assembly since Microsoft.CSharp is a FX assembly Assert.Single(unreferencedAssms); @@ -96,13 +96,13 @@ public static void FindUnreferencedAssemblies_UnreferencedAssemblies_2() public static void FindUnreferencedAssemblies_UnreferencedAssemblies_WithNullInSpecifiedList() { var catalog = Substitute.For(); - catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(s_unreferencedAssemblies[0])).Returns(true); + catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(UnreferencedAssemblies[0])).Returns(true); var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); var specifiedUserAssemblies = new List() { new AssemblyInfo() { FileVersion = string.Empty, AssemblyIdentity = "MyAssembly" }, null }; - var unreferencedAssms = engine.FindUnreferencedAssemblies(s_unreferencedAssemblies, specifiedUserAssemblies).ToList(); + var unreferencedAssms = engine.FindUnreferencedAssemblies(UnreferencedAssemblies, specifiedUserAssemblies).ToList(); // 0 missing assembly since Microsoft.CSharp is a fx assembly and we specified MyAssembly Assert.Empty(unreferencedAssms); @@ -112,13 +112,13 @@ public static void FindUnreferencedAssemblies_UnreferencedAssemblies_WithNullInS public static void FindUnreferencedAssemblies_UnreferencedAssemblies_WithNullInUnrefList() { var catalog = Substitute.For(); - catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(s_unreferencedAssemblies[0])).Returns(true); + catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(UnreferencedAssemblies[0])).Returns(true); var recommendations = Substitute.For(); var engine = new AnalysisEngine(catalog, recommendations, null); var specifiedUserAssemblies = new List() { new AssemblyInfo() { FileVersion = string.Empty, AssemblyIdentity = "MyAssembly" } }; - var listWithNulls = s_unreferencedAssemblies.Concat(new List() { null }).ToList(); + var listWithNulls = UnreferencedAssemblies.Concat(new List() { null }).ToList(); var unreferencedAssms = engine.FindUnreferencedAssemblies(listWithNulls, specifiedUserAssemblies).ToList(); diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs index ed5fba50c..9103f5af4 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs @@ -245,7 +245,7 @@ private Stream GetBreakingChangeMarkdown(string resourceName) #endregion #region Expected Breaking Changes - public static BreakingChange TemplateBC = new BreakingChange + private static readonly BreakingChange TemplateBC = new BreakingChange { Id = "100", Title = "Breaking Change Title", @@ -263,7 +263,7 @@ private Stream GetBreakingChangeMarkdown(string resourceName) Notes = "Source analyzer status: Not usefully detectable with an analyzer" }; - public static BreakingChange ListTBC = new BreakingChange + private static readonly BreakingChange ListTBC = new BreakingChange { Id = "5", Title = "List.ForEach", @@ -279,7 +279,7 @@ private Stream GetBreakingChangeMarkdown(string resourceName) Notes = "This introduces an exception, but requires retargeting\nSource analyzer status: Pri 1, source and binary done (MikeRou)" }; - public static BreakingChange UriBC = new BreakingChange + private static readonly BreakingChange UriBC = new BreakingChange { Id = "6", Title = "System.Uri", @@ -303,7 +303,7 @@ private Stream GetBreakingChangeMarkdown(string resourceName) Notes = "Changes IRI parsing, requires access to parameters to detect\nSource analyzer status: Pri 1, source done (AlPopa)" }; - public static BreakingChange LongPathSupportBC = new BreakingChange + private static readonly BreakingChange LongPathSupportBC = new BreakingChange { Id = "162", Title = "Long path support", @@ -319,7 +319,7 @@ private Stream GetBreakingChangeMarkdown(string resourceName) Categories = new[] { "Core" } }; - public static BreakingChange OptionalBC = new BreakingChange + private static readonly BreakingChange OptionalBC = new BreakingChange { Id = "50", Title = "Opt-in break to revert from different 4.5 SQL generation to simpler 4.0 SQL generation", @@ -334,7 +334,7 @@ private Stream GetBreakingChangeMarkdown(string resourceName) Categories = new[] { "Entity Framework" } }; - public static BreakingChange PointerStackBC = new BreakingChange + private static readonly BreakingChange PointerStackBC = new BreakingChange { Id = "172", Title = "WPF Pointer-Based Touch Stack", @@ -349,7 +349,7 @@ private Stream GetBreakingChangeMarkdown(string resourceName) Categories = new[] { "Windows Presentation Foundation (WPF)" } }; - public static BreakingChange AccessibilityBC = new BreakingChange + private static readonly BreakingChange AccessibilityBC = new BreakingChange { Title = "ASP.NET Accessibility Improvements in .NET 4.7.1", ImpactScope = BreakingChangeImpact.Minor, diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs index 742f02734..d77360734 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs @@ -110,7 +110,7 @@ public string GetSourceCompatibilityEquivalent(string docId) throw new NotImplementedException(); } - public IEnumerable GetSupportedVersions(string DocId) + public IEnumerable GetSupportedVersions(string docId) { throw new NotImplementedException(); } From ac782cc2f1c8ca1858fb7e8bc0dc51179d25e72f Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Thu, 20 Sep 2018 10:52:39 -0700 Subject: [PATCH 10/17] Fix build warning (#711) --- .../SystemObjectFinderTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs index df6433cdb..c532cbefb 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs @@ -89,13 +89,13 @@ public void ResourceAssembliesGetSkipped() [Theory] public void LookInFilePassedInAssembly(string name) { - var Source = @" + var source = @" .assembly " + name + @" { .ver 1:0:0:0 } "; var objectFinder = new SystemObjectFinder(new DotNetFrameworkFilter()); - var file = TestAssembly.CreateFromIL(Source, name, _output); + var file = TestAssembly.CreateFromIL(source, name, _output); using (var stream = file.OpenRead()) using (var peFile = new PEReader(stream)) From a90b32b1a1b7d9c2a6d822c04878f266423d8a69 Mon Sep 17 00:00:00 2001 From: Alex Ghiondea Date: Tue, 25 Sep 2018 10:43:27 -0700 Subject: [PATCH 11/17] Produce a DGML graph from the ApiPort data (#695) * Add project for generating a DGML file from the results. * Capture information about the referenced assemblies for each user assembly * Introduce a graph representation of the data * Add methods to provide access to the raw number of APIs that are called (available and not) * Display the portability of the references for each assembly --- PortabilityTools.sln | 51 +++++++ src/ApiPort/ApiPort/ApiPort.Offline.csproj | 1 + .../DependencyFinderEngineHelper.cs | 21 ++- .../DGMLManager.cs | 138 ++++++++++++++++++ .../DGMLOutputWriter.cs | 138 ++++++++++++++++++ ...crosoft.Fx.Portability.Reports.DGML.csproj | 10 ++ .../ReferenceGraph.cs | 70 +++++++++ .../ReferenceNode.cs | 124 ++++++++++++++++ .../ReferenceNodeComparer.cs | 21 +++ .../Analyzer/RequestAnalyzer.cs | 3 +- .../ObjectModel/AnalyzeResponse.cs | 3 + .../ObjectModel/AssemblyInfo.cs | 3 + .../Reporting/ObjectModel/TargetUsageInfo.cs | 4 + 13 files changed, 585 insertions(+), 2 deletions(-) create mode 100644 src/lib/Microsoft.Fx.Portability.Reports.DGML/DGMLManager.cs create mode 100644 src/lib/Microsoft.Fx.Portability.Reports.DGML/DGMLOutputWriter.cs create mode 100644 src/lib/Microsoft.Fx.Portability.Reports.DGML/Microsoft.Fx.Portability.Reports.DGML.csproj create mode 100644 src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceGraph.cs create mode 100644 src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceNode.cs create mode 100644 src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceNodeComparer.cs diff --git a/PortabilityTools.sln b/PortabilityTools.sln index 1a110c10c..27cee9c22 100644 --- a/PortabilityTools.sln +++ b/PortabilityTools.sln @@ -82,6 +82,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiPort", "ApiPort", "{C2CF EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{CB5759DE-9D7B-4B21-89BC-E81920D611BB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Fx.Portability.Reports.DGML", "src\lib\Microsoft.Fx.Portability.Reports.DGML\Microsoft.Fx.Portability.Reports.DGML.csproj", "{1B6E53A7-9180-4D79-9556-E5CE59483EA1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1046,6 +1048,54 @@ Global {2DFBC0D7-E65F-4F85-9E60-5F6C4BA8F4FE}.Ubuntu_Release|x64.Build.0 = Release|Any CPU {2DFBC0D7-E65F-4F85-9E60-5F6C4BA8F4FE}.Ubuntu_Release|x86.ActiveCfg = Release|Any CPU {2DFBC0D7-E65F-4F85-9E60-5F6C4BA8F4FE}.Ubuntu_Release|x86.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Debug|ARM.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Debug|x64.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Debug|x64.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Debug|x86.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Debug|x86.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Debug|Any CPU.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Debug|ARM.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Debug|ARM.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Debug|x64.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Debug|x64.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Debug|x86.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Debug|x86.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Release|Any CPU.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Release|Any CPU.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Release|ARM.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Release|ARM.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Release|x64.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Release|x64.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Release|x86.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Osx_Release|x86.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Release|Any CPU.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Release|ARM.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Release|ARM.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Release|x64.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Release|x64.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Release|x86.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Release|x86.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Debug|Any CPU.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Debug|ARM.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Debug|ARM.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Debug|x64.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Debug|x64.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Debug|x86.ActiveCfg = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Debug|x86.Build.0 = Debug|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Release|Any CPU.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Release|Any CPU.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Release|ARM.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Release|ARM.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Release|x64.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Release|x64.Build.0 = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Release|x86.ActiveCfg = Release|Any CPU + {1B6E53A7-9180-4D79-9556-E5CE59483EA1}.Ubuntu_Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1076,6 +1126,7 @@ Global {D66AC566-3B80-46F0-8687-3C5F4D203F1A} = {6234AABE-C4F3-4094-9C0D-FFD589235DBE} {C2CF3FE7-5A24-4FEF-B833-86FBAC5D5731} = {7DC7AA2C-0401-495B-B42C-32F44085EBE6} {CB5759DE-9D7B-4B21-89BC-E81920D611BB} = {7DC7AA2C-0401-495B-B42C-32F44085EBE6} + {1B6E53A7-9180-4D79-9556-E5CE59483EA1} = {D66AC566-3B80-46F0-8687-3C5F4D203F1A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8E8B2DB2-4847-4909-8631-A995D50F10EF} diff --git a/src/ApiPort/ApiPort/ApiPort.Offline.csproj b/src/ApiPort/ApiPort/ApiPort.Offline.csproj index e990a7516..5d737d5b6 100644 --- a/src/ApiPort/ApiPort/ApiPort.Offline.csproj +++ b/src/ApiPort/ApiPort/ApiPort.Offline.csproj @@ -8,6 +8,7 @@ + diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs index da5a1a923..96b6545bf 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs @@ -29,7 +29,8 @@ public DependencyFinderEngineHelper(IDependencyFilter assemblyFilter, MetadataRe Location = file.Name, AssemblyIdentity = metadataReader.FormatAssemblyInfo().ToString(), FileVersion = file.Version ?? string.Empty, - TargetFrameworkMoniker = metadataReader.GetTargetFrameworkMoniker() ?? string.Empty + TargetFrameworkMoniker = metadataReader.GetTargetFrameworkMoniker() ?? string.Empty, + AssemblyReferences = ComputeAssemblyReferences(metadataReader) }; // Get assembly info @@ -39,6 +40,24 @@ public DependencyFinderEngineHelper(IDependencyFilter assemblyFilter, MetadataRe _currentAssemblyName = _reader.GetString(assemblyDefinition.Name); } + private IList ComputeAssemblyReferences(MetadataReader metadataReader) + { + var refs = new List(); + foreach (var handle in _reader.AssemblyReferences) + { + try + { + var entry = _reader.GetAssemblyReference(handle); + + refs.Add(metadataReader.FormatAssemblyInfo(entry)); + } + catch (BadImageFormatException) + { + } + } + return refs; + } + public AssemblyInfo CallingAssembly { get; } public IList MemberDependency { get; } diff --git a/src/lib/Microsoft.Fx.Portability.Reports.DGML/DGMLManager.cs b/src/lib/Microsoft.Fx.Portability.Reports.DGML/DGMLManager.cs new file mode 100644 index 000000000..b877d5ab8 --- /dev/null +++ b/src/lib/Microsoft.Fx.Portability.Reports.DGML/DGMLManager.cs @@ -0,0 +1,138 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml.Linq; + +namespace Microsoft.Fx.Portability.Reports.DGML +{ + /// + /// This class will manage the IDs that we generate for the DGML graph + /// + internal class DGMLManager + { + private readonly Dictionary _nodesDictionary = new Dictionary(); + + private readonly XElement nodes; + + private readonly XElement links; + + private readonly XNamespace _nameSpace = "http://schemas.microsoft.com/vs/2009/dgml"; + #region DGML template + private readonly string _template = + @" + + + + + + + + + + + + + + + + + + + + + W + "; + #endregion + + private XDocument file; + + public DGMLManager() + { + file = XDocument.Parse(_template); + XElement root = file.Root; + + nodes = root.Element(_nameSpace + "Nodes"); + links = root.Element(_nameSpace + "Links"); + } + + public void SetTitle(string title) + { + file.Root.SetAttributeValue("Title", title); + } + + public bool TryGetId(string value, out Guid frameworkGuid) + { + return _nodesDictionary.TryGetValue(value, out frameworkGuid); + } + + internal void AddLink(Guid source, Guid target, string category = null) + { + var element = new XElement(_nameSpace + "Link", + new XAttribute("Source", source), + new XAttribute("Target", target)); + + if (category != null) + { + element.SetAttributeValue("Category", category); + } + + links.Add(element); + } + + internal void AddNode(Guid commentGuid, string missingTypes, string category) + { + AddNode(commentGuid, missingTypes, category, null, null); + } + + internal void AddNode(Guid id, string label, string category, double? portabilityIndex, string group) + { + var element = new XElement(_nameSpace + "Node", + new XAttribute("Id", id), + new XAttribute("Label", label), + new XAttribute("Category", category)); + + if (portabilityIndex != null) + { + element.SetAttributeValue("PortabilityIndex", portabilityIndex); + } + + if (group != null) + { + element.SetAttributeValue("Group", group); + } + + nodes.Add(element); + } + + internal void Save(Stream stream) + { + using (var ms = new MemoryStream()) + { + file.Save(ms); + ms.Position = 0; + ms.CopyTo(stream); + } + } + + internal Guid GetOrCreateGuid(string nodeLabel) + { + if (!_nodesDictionary.TryGetValue(nodeLabel, out Guid guid)) + { + guid = Guid.NewGuid(); + _nodesDictionary.Add(nodeLabel, guid); + } + + return guid; + } + } +} diff --git a/src/lib/Microsoft.Fx.Portability.Reports.DGML/DGMLOutputWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.DGML/DGMLOutputWriter.cs new file mode 100644 index 000000000..8ab0f63d9 --- /dev/null +++ b/src/lib/Microsoft.Fx.Portability.Reports.DGML/DGMLOutputWriter.cs @@ -0,0 +1,138 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Fx.Portability.ObjectModel; +using Microsoft.Fx.Portability.Reporting; +using Microsoft.Fx.Portability.Reporting.ObjectModel; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Versioning; +using System.Text; +using System.Xml.Linq; + +namespace Microsoft.Fx.Portability.Reports.DGML +{ + public class DGMLOutputWriter : IReportWriter + { + public ResultFormatInformation Format => new ResultFormatInformation() + { + DisplayName = "DGML", + MimeType = "application/xml", + FileExtension = ".dgml" + }; + + private readonly DGMLManager dgml = new DGMLManager(); + + public void WriteStream(Stream stream, AnalyzeResponse response) + { + 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: missingTypes.Length == 0 ? 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; + } + + 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 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); + } + + private void GenerateTargetContainers(IList targets) + { + for (int i = 0; i < targets.Count; i++) + { + string targetFramework = targets[i].FullName; + Guid nodeGuid = dgml.GetOrCreateGuid(targetFramework); + dgml.AddNode(nodeGuid, targetFramework, "Target", null, group: "Expanded"); + } + } + + private static string GetCategory(double probabilityIndex) + { + if (probabilityIndex == 100.0) + return "VeryHigh"; + if (probabilityIndex >= 75.0) + return "High"; + if (probabilityIndex >= 50.0) + return "Medium"; + if (probabilityIndex >= 30.0) + return "MediumLow"; + + return "Low"; + } + } +} diff --git a/src/lib/Microsoft.Fx.Portability.Reports.DGML/Microsoft.Fx.Portability.Reports.DGML.csproj b/src/lib/Microsoft.Fx.Portability.Reports.DGML/Microsoft.Fx.Portability.Reports.DGML.csproj new file mode 100644 index 000000000..d2e70e6da --- /dev/null +++ b/src/lib/Microsoft.Fx.Portability.Reports.DGML/Microsoft.Fx.Portability.Reports.DGML.csproj @@ -0,0 +1,10 @@ + + + + netstandard1.3 + + + + + + diff --git a/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceGraph.cs b/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceGraph.cs new file mode 100644 index 000000000..b564c481e --- /dev/null +++ b/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceGraph.cs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Fx.Portability.ObjectModel; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Fx.Portability.Reports.DGML +{ + internal class ReferenceGraph + { + public Dictionary Nodes { get; } + + public static ReferenceGraph CreateGraph(AnalyzeResponse response) + { + ReferenceGraph rg = new ReferenceGraph(); + AnalyzeRequest request = response.Request; + + // get the list of assemblies that have some data reported for them. + var assembliesWithData = response.ReportingResult.GetAssemblyUsageInfo().ToDictionary(x => x.SourceAssembly.AssemblyIdentity, x => x.UsageData); + + var unresolvedAssemblies = response.ReportingResult.GetUnresolvedAssemblies().Select(x => x.Key).ToList(); + + // Add every user specified assembly to the graph + foreach (var userAsem in request.UserAssemblies) + { + var node = rg.GetOrAddNodeForAssembly(new ReferenceNode(userAsem.AssemblyIdentity)); + + // For this node, make sure we capture the data, if we have it. + if (assembliesWithData.ContainsKey(node.Assembly)) + { + node.UsageData = assembliesWithData[node.Assembly]; + } + + // create nodes for all the references, if non platform. + foreach (var reference in userAsem.AssemblyReferences) + { + if (!(assembliesWithData.ContainsKey(reference.ToString()) || unresolvedAssemblies.Contains(reference.ToString()))) + { + // platform reference (not in the user specified asssemblies and not an unresolved assembly. + continue; + } + + var refNode = rg.GetOrAddNodeForAssembly(new ReferenceNode(reference.ToString())); + + // if the reference is missing, flag it as such. + refNode.IsMissing = unresolvedAssemblies.Contains(reference.ToString()); + + node.AddReferenceToNode(refNode); + } + } + + return rg; + } + + public ReferenceGraph() + { + Nodes = new Dictionary(ReferenceNodeComparer.Instance); + } + + public ReferenceNode GetOrAddNodeForAssembly(ReferenceNode node) + { + if (Nodes.ContainsKey(node)) + return Nodes[node]; + + Nodes.Add(node, node); + return node; + } + } +} diff --git a/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceNode.cs b/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceNode.cs new file mode 100644 index 000000000..682f115c9 --- /dev/null +++ b/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceNode.cs @@ -0,0 +1,124 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Fx.Portability.Reporting.ObjectModel; +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Microsoft.Fx.Portability.Reports.DGML +{ + internal class ReferenceNode + { + private bool _searchInGraph = false; + + public List UsageData { get; set; } + + public string Assembly { get; } + + public bool Unresolved { get; set; } + + public HashSet Nodes { get; } + + public bool IsMissing { get; internal set; } + + public string SimpleName + { + get + { + if (!IsMissing) + return new AssemblyName(Assembly).Name; + + return "Unresolved: " + new AssemblyName(Assembly).Name; + } + } + + public ReferenceNode(string assemblyName, bool unresolved = false) + { + Assembly = assemblyName; + Unresolved = unresolved; + Nodes = new HashSet(ReferenceNodeComparer.Instance); + } + + public override int GetHashCode() + { + return Assembly.GetHashCode(); + } + + public void AddReferenceToNode(ReferenceNode node) + { + Nodes.Add(node); + } + + public override string ToString() + { + return Assembly; + } + + public double GetPortabilityIndex(int target) + { + return UsageData[target].PortabilityIndex; + } + + public double GetPortabilityIndexForReferences(int target) + { + // if we don't have any outgoing references, it is a good sign! + if (Nodes.Count == 0) + return 1; + + // sum up the number of calls to available APIs and the ones for not available APIs for references. + if (!TryGetAPICountFromReferences(target, out int availableApis, out int unavailableApis)) + { + // Cycle detected + return 1; + } + else + { + // remove the calls from the current node. + availableApis -= UsageData[target].GetAvailableAPICalls(); + unavailableApis -= UsageData[target].GetUnavailableAPICalls(); + + // prevent Div/0 + if (availableApis == 0 && unavailableApis == 0) + return 0; + + return availableApis / ((double)availableApis + unavailableApis); + } + } + + public bool TryGetAPICountFromReferences(int target, out int availAPIs, out int unavailAPIs) + { + availAPIs = UsageData[target].GetAvailableAPICalls(); + unavailAPIs = UsageData[target].GetUnavailableAPICalls(); + + // We are going to use a flag on the object to detect if we have a reference cycle while computing the APIs for the references. + if (_searchInGraph == true) + { + // Cycle!!! + _searchInGraph = false; // Reset this flag + return false; + } + else + { + _searchInGraph = true; + } + + foreach (var item in Nodes) + { + if (!item.TryGetAPICountFromReferences(target, out int refCountAvail, out int refCountUnavail)) + { + // Cycle! + _searchInGraph = false; // Reset this flag + + return false; + } + + availAPIs += refCountAvail; + unavailAPIs += refCountUnavail; + } + + _searchInGraph = false; + return true; + } + } +} diff --git a/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceNodeComparer.cs b/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceNodeComparer.cs new file mode 100644 index 000000000..71a86e96b --- /dev/null +++ b/src/lib/Microsoft.Fx.Portability.Reports.DGML/ReferenceNodeComparer.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System.Collections.Generic; + +namespace Microsoft.Fx.Portability.Reports.DGML +{ + internal class ReferenceNodeComparer : IEqualityComparer + { + public static ReferenceNodeComparer Instance { get; } = new ReferenceNodeComparer(); + + public bool Equals(ReferenceNode x, ReferenceNode y) + { + return x.Assembly == y.Assembly; + } + + public int GetHashCode(ReferenceNode obj) + { + return obj.Assembly.GetHashCode(); + } + } +} diff --git a/src/lib/Microsoft.Fx.Portability/Analyzer/RequestAnalyzer.cs b/src/lib/Microsoft.Fx.Portability/Analyzer/RequestAnalyzer.cs index 898789cd6..8aa678df9 100644 --- a/src/lib/Microsoft.Fx.Portability/Analyzer/RequestAnalyzer.cs +++ b/src/lib/Microsoft.Fx.Portability/Analyzer/RequestAnalyzer.cs @@ -102,7 +102,8 @@ public AnalyzeResponse AnalyzeRequest(AnalyzeRequest request, string submissionI SubmissionId = submissionId, BreakingChanges = breakingChanges, BreakingChangeSkippedAssemblies = breakingChangeSkippedAssemblies, - NuGetPackages = nugetPackages + NuGetPackages = nugetPackages, + Request = request }; } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/AnalyzeResponse.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/AnalyzeResponse.cs index 9d9564348..e319ee3df 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/AnalyzeResponse.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/AnalyzeResponse.cs @@ -30,6 +30,9 @@ public AnalyzeResponse() public IList Targets { get; set; } + [JsonIgnore] + public AnalyzeRequest Request { get; set; } + [JsonIgnore] public IList NuGetPackages { get; set; } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs index 7e85c1c7c..ac57caff6 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs @@ -4,6 +4,7 @@ using Microsoft.Fx.Portability.Resources; using Newtonsoft.Json; using System; +using System.Collections.Generic; using System.Globalization; namespace Microsoft.Fx.Portability.ObjectModel @@ -60,6 +61,8 @@ public string TargetFrameworkMoniker } } + public IList AssemblyReferences { get; set; } + public bool IsExplicitlySpecified { get; set; } = true; public override bool Equals(object obj) diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs index f1fb9153c..f19069422 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs @@ -20,6 +20,10 @@ public void IncrementCallsToUnavailableApi() Interlocked.Increment(ref _callsToUnavailableAPIs); } + public int GetAvailableAPICalls() => _callsToAvailableAPIs; + + public int GetUnavailableAPICalls() => _callsToUnavailableAPIs; + public double PortabilityIndex { get From 9cf6d0100cb5f04cf3be7cdf172ce0db02c207f3 Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Fri, 28 Sep 2018 13:28:22 -0700 Subject: [PATCH 12/17] More style cop rule fixes. Part 5 (#712) * Unsuppressing SA1500, SA1501, SA1503 * Fixing SA1500: Align braces * Fixing SA1501: Statements {} should not be on a single line * Fixes SA1503 * Fixing missing braces --- rules.ruleset | 3 -- .../ServiceProvider.cs | 3 +- .../Models/TargetPlatform.cs | 46 ++++++++-------- .../SourceMapping/CciSourceLineMapper.cs | 24 +++++---- .../ViewModels/OutputViewModel.cs | 4 +- .../AssemblyRedirectResolver.cs | 8 ++- .../OutputWindowWriter.cs | 4 +- .../ApiPort.VisualStudio/Views/OptionsPage.cs | 2 + .../Analyzer/DependencyFinderEngine.cs | 6 ++- .../DocIdExtensions.cs | 25 ++++++--- .../MemberMetadataInfo.cs | 24 +++++++-- .../ReflectionMetadataDependencyInfo.cs | 28 ++++++---- .../OpenXmlExtensions.cs | 10 ++++ .../JsonReportWriter.cs | 6 ++- .../Analysis/AnalysisEngine.cs | 6 +++ .../BreakingChangeParser.cs | 27 ++++++++-- .../CompressedHttpClient.cs | 3 +- .../DataExtensions.cs | 48 ++++++++++------- .../ObjectModel/AssemblyInfo.cs | 2 + .../ObjectModel/CloudApiCatalogLookup.cs | 4 ++ .../ObjectModel/IgnoreAssemblyInfo.cs | 5 +- .../ObjectModel/ProjectSubmission.cs | 5 +- .../Reporting/ObjectModel/MissingTypeInfo.cs | 2 + .../Reporting/ObjectModel/TargetUsageInfo.cs | 2 + .../Reporting/ReportFileWriter.cs | 10 +++- .../Reporting/ReportGenerator.cs | 10 ++-- .../Microsoft.Fx.Portability/TargetMapper.cs | 7 ++- .../ApiPortVS.Tests/TargetPlatformTests.cs | 24 ++++++--- .../TestAssembly.cs | 4 +- .../ManagedMetadataReaderTests.cs | 3 +- .../SystemObjectFinderTests.cs | 52 +++++++++++-------- .../TestAssembly.cs | 6 ++- .../BreakingChangeParserTests.cs | 6 ++- .../ObjectModel/IgnoreAssemblyInfoTests.cs | 12 +++-- .../ReportFileWriterTests.cs | 3 +- .../TargetMapTests.cs | 32 +++++++----- .../TestData/TestCatalog.cs | 12 ++--- .../TestData/TestDotNetCatalog.cs | 27 ++++++---- 38 files changed, 332 insertions(+), 173 deletions(-) diff --git a/rules.ruleset b/rules.ruleset index 045f1265b..d685d3995 100644 --- a/rules.ruleset +++ b/rules.ruleset @@ -60,10 +60,7 @@ - - - diff --git a/src/ApiPort/ApiPort.VisualStudio.2017/ServiceProvider.cs b/src/ApiPort/ApiPort.VisualStudio.2017/ServiceProvider.cs index d47b09806..a924b7cd0 100644 --- a/src/ApiPort/ApiPort.VisualStudio.2017/ServiceProvider.cs +++ b/src/ApiPort/ApiPort.VisualStudio.2017/ServiceProvider.cs @@ -13,7 +13,8 @@ public class ServiceProvider : Module { protected override void Load(ContainerBuilder builder) { - builder.RegisterAdapter(serviceProvider => { + builder.RegisterAdapter(serviceProvider => + { var componentModel = serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel; var projectServiceAccessor = componentModel.GetService(); return projectServiceAccessor.GetProjectService(); diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatform.cs b/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatform.cs index 77304540a..e92b95ae4 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatform.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/Models/TargetPlatform.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.Fx.Portability.ObjectModel; using System; using System.Collections.Generic; using System.Linq; @@ -26,7 +25,9 @@ public TargetPlatform() public override bool Equals(object obj) { if (!(obj is TargetPlatform compared)) + { return false; + } return string.Equals(Name, compared.Name, StringComparison.Ordinal) && Versions.SequenceEqual(compared.Versions); @@ -104,36 +105,37 @@ public int CompareTo(TargetPlatform other) // information, like whether e1 comes before e2 (returning -1) or e1 // comes after e2 (returning +1). using (var e1 = Versions.GetEnumerator()) - using (var e2 = other.Versions.GetEnumerator()) { - while (e1.MoveNext()) + using (var e2 = other.Versions.GetEnumerator()) { - // `this` has more Versions than the compared object, so - // `this` should come after the compared object since all - // other elements up until this point were equal. - if (!e2.MoveNext()) + while (e1.MoveNext()) { - return 1; + // `this` has more Versions than the compared object, so + // `this` should come after the compared object since all + // other elements up until this point were equal. + if (!e2.MoveNext()) + { + return 1; + } + else if (Equals(e1.Current, e2.Current)) + { + continue; + } + else + { + return e1.Current.Version.CompareTo(e2.Current.Version); + } } - else if (Equals(e1.Current, e2.Current)) - { - continue; - } - else + + // Compared has more Versions than `this`. `this` comes first + if (e2.MoveNext()) { - return e1.Current.Version.CompareTo(e2.Current.Version); + return -1; } - } - // Compared has more Versions than `this`. `this` comes first - if (e2.MoveNext()) - { - return -1; + return 0; } - - return 0; } - } } } diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciSourceLineMapper.cs b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciSourceLineMapper.cs index 32fef8bce..4a49b95bc 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciSourceLineMapper.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciSourceLineMapper.cs @@ -21,20 +21,24 @@ public CciSourceLineMapper(IFileSystem fileSystem, TextWriter textOutputTarget, public override IEnumerable 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 + using (var pdbFs = File.OpenRead(pdbPath)) { - PreorderVisitor = metadataVisitor, - TraverseIntoMethodBodies = true - }; + 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); + var cciAssembly = host.LoadAssembly(assemblyPath); + traverser.Traverse(cciAssembly); - return metadataVisitor.FoundItems; + return metadataVisitor.FoundItems; + } + } } } } diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/ViewModels/OutputViewModel.cs b/src/ApiPort/ApiPort.VisualStudio.Common/ViewModels/OutputViewModel.cs index 448505247..76fcdbf4c 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/ViewModels/OutputViewModel.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/ViewModels/OutputViewModel.cs @@ -88,7 +88,9 @@ private static void SaveFileAs(string path) File.Copy(path, fileSaveDialog.FileName); } } - catch (Exception) { } + catch (Exception) + { + } } private class DelegateCommand : ICommand diff --git a/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs b/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs index decca7afa..5b2e4cadc 100644 --- a/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs +++ b/src/ApiPort/ApiPort.VisualStudio/AssemblyRedirectResolver.cs @@ -24,7 +24,10 @@ internal class AssemblyRedirectResolver public AssemblyRedirectResolver(string configFile) { - XName GetFullName(string name) { return XName.Get(name, "urn:schemas-microsoft-com:asm.v1"); } + XName GetFullName(string name) + { + return XName.Get(name, "urn:schemas-microsoft-com:asm.v1"); + } var xml = XDocument.Load(configFile); var redirects = from element in xml.Descendants(GetFullName("dependentAssembly")) @@ -41,7 +44,8 @@ public AssemblyRedirectResolver(string configFile) public AssemblyRedirectResolver(DirectoryInfo assemblyFolder) { var redirects = assemblyFolder.GetFiles("*.dll") - .Select(dll => { + .Select(dll => + { var name = AssemblyName.GetAssemblyName(dll.FullName); var publicKeyToken = name.GetPublicKeyToken().Aggregate(string.Empty, (s, b) => s += b.ToString("x2", CultureInfo.InvariantCulture)); return new AssemblyRedirect(name.Name, name.Version.ToString(), publicKeyToken); diff --git a/src/ApiPort/ApiPort.VisualStudio/OutputWindowWriter.cs b/src/ApiPort/ApiPort.VisualStudio/OutputWindowWriter.cs index cc22244a6..5aef28f96 100644 --- a/src/ApiPort/ApiPort.VisualStudio/OutputWindowWriter.cs +++ b/src/ApiPort/ApiPort.VisualStudio/OutputWindowWriter.cs @@ -43,7 +43,9 @@ public async Task ShowWindowAsync() Window window = _dte.Windows.Item(Constants.VsWindowKindOutput); window.Activate(); } - catch (Exception) { } + catch (Exception) + { + } } public async Task ClearWindowAsync() diff --git a/src/ApiPort/ApiPort.VisualStudio/Views/OptionsPage.cs b/src/ApiPort/ApiPort.VisualStudio/Views/OptionsPage.cs index 452376404..9397583eb 100644 --- a/src/ApiPort/ApiPort.VisualStudio/Views/OptionsPage.cs +++ b/src/ApiPort/ApiPort.VisualStudio/Views/OptionsPage.cs @@ -49,7 +49,9 @@ private System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, protected override void Dispose(bool disposing) { if (_optionsPageControl != null) + { _optionsPageControl.Dispose(); + } base.Dispose(disposing); } diff --git a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs index 173807ca5..41d5c59a0 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs @@ -95,7 +95,9 @@ private IEnumerable GetDependencies(string assemblyLocation) { callingAssembly = e.Referrer.GetAssemblyReference().AssemblyIdentity.Format(); } - catch { } + catch + { + } HashSet newValue = new HashSet { @@ -139,7 +141,9 @@ private IEnumerable GetDependencies(string assemblyLocation) foreach (var reference in cciAssembly.GetTypeMemberReferences()) { if (reference.ContainingType.GetAssemblyReference() == null) + { continue; + } string definedIn = reference.ContainingType.GetAssemblyReference().ContainingAssembly.AssemblyIdentity.Format(); // return the type diff --git a/src/lib/Microsoft.Fx.Portability.Cci/DocIdExtensions.cs b/src/lib/Microsoft.Fx.Portability.Cci/DocIdExtensions.cs index 4aa92191f..c41e4ec3a 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/DocIdExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/DocIdExtensions.cs @@ -63,16 +63,21 @@ public static string RefDocId(this IReference reference) Contract.Requires(reference != null); if (reference is ITypeReference type) + { return type.DocId(); - - if (reference is ITypeMemberReference member) + } + else if (reference is ITypeMemberReference member) + { return member.DocId(); - - if (reference is IUnitNamespaceReference ns) + } + else if (reference is IUnitNamespaceReference ns) + { return ns.DocId(); - - if (reference is IAssemblyReference assembly) + } + else if (reference is IAssemblyReference assembly) + { return assembly.DocId(); + } Contract.Assert(false, string.Format(CultureInfo.CurrentUICulture, LocalizedStrings.FellThroughCasesIn, "DocIdExtensions.RefDocId()", reference.GetType())); return LocalizedStrings.UnknownReferenceType; @@ -83,12 +88,18 @@ public static HashSet ReadDocIds(string docIdsFile) HashSet ids = new HashSet(); if (!File.Exists(docIdsFile)) + { return ids; + } foreach (string id in File.ReadAllLines(docIdsFile)) { - if (string.IsNullOrWhiteSpace(id) || id.StartsWith("#", StringComparison.Ordinal) || id.StartsWith("//", StringComparison.Ordinal)) + if (string.IsNullOrWhiteSpace(id) + || id.StartsWith("#", StringComparison.Ordinal) + || id.StartsWith("//", StringComparison.Ordinal)) + { continue; + } ids.Add(id.Trim()); } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs index 1c9e802fb..429afbfce 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfo.cs @@ -248,12 +248,26 @@ private static string GetDocIdSafeMemberName(string name) char[] newName = new char[name.Length]; for (int i = 0; i < name.Length; i++) { - if (name[i] == '<') newName[i] = '{'; - else if (name[i] == '>') newName[i] = '}'; - else if (name[i] == '.') newName[i] = '#'; - else if (name[i] == ',') newName[i] = '@'; - else newName[i] = name[i]; + switch (name[i]) + { + case '<': + newName[i] = '{'; + break; + case '>': + newName[i] = '}'; + break; + case '.': + newName[i] = '#'; + break; + case ',': + newName[i] = '@'; + break; + default: + newName[i] = name[i]; + break; + } } + return new string(newName); } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs index 802803263..eefea5193 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs @@ -117,27 +117,35 @@ private IEnumerable GetDependencies(IAssemblyFile file) try { using (var stream = file.OpenRead()) - using (var peFile = new PEReader(stream)) { - var metadataReader = GetMetadataReader(peFile); + using (var peFile = new PEReader(stream)) + { + var metadataReader = GetMetadataReader(peFile); - AddReferencedAssemblies(metadataReader); + AddReferencedAssemblies(metadataReader); - var helper = new DependencyFinderEngineHelper(_assemblyFilter, metadataReader, file, _objectFinder); - helper.ComputeData(); + var helper = new DependencyFinderEngineHelper(_assemblyFilter, metadataReader, file, _objectFinder); + helper.ComputeData(); - // Remember this assembly as a user assembly. - _userAssemblies.Add(helper.CallingAssembly); + // Remember this assembly as a user assembly. + _userAssemblies.Add(helper.CallingAssembly); - return helper.MemberDependency; + return helper.MemberDependency; + } } } catch (Exception exc) { // InvalidPEAssemblyExceptions may be expected and indicative of a non-PE file - if (exc is InvalidPEAssemblyException) throw; + if (exc is InvalidPEAssemblyException) + { + throw; + } // Occurs when we cannot find the System.Object assembly. - if (exc is SystemObjectNotFoundException) throw; + if (exc is SystemObjectNotFoundException) + { + throw; + } // Other exceptions are unexpected, though, and will benefit from // more details on the scenario that hit them diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs index df27b177b..066f9f9fe 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs @@ -48,13 +48,17 @@ public static Worksheet AddWorksheet(this SpreadsheetDocument spreadsheet, strin public static Table AddTable(this Worksheet worksheet, int rowStart, int rowCount, int columnStart, params string[] headers) { if (rowCount == 1) + { rowCount++; + } string range = ComputeRange(rowStart, rowCount, columnStart, headers.Length); var sheetViews = worksheet.GetFirstChild(); if (sheetViews == null) + { sheetViews = worksheet.InsertAt(new SheetViews(), 0); + } var sheetView = sheetViews.AppendChild(new SheetView()); sheetView.WorkbookViewId = 0; @@ -74,7 +78,9 @@ public static Table AddTable(this Worksheet worksheet, int rowStart, int rowCoun }; var tableParts = worksheet.GetFirstChild(); if (tableParts == null) + { tableParts = worksheet.AppendChild(new TableParts()); + } tableParts.AppendChild(tp); @@ -147,7 +153,9 @@ public static void AddRow(this Worksheet ws, params object[] data) { var sd = ws.GetFirstChild(); if (sd == null) + { sd = ws.AppendChild(new SheetData()); + } var row = sd.AppendChild(new Row()); @@ -218,7 +226,9 @@ private static string GetColumnName(int index) var sb = new StringBuilder(); if (index >= Alphabet.Length) + { sb.Append(Alphabet[(index / Alphabet.Length) - 1]); + } sb.Append(Alphabet[index % Alphabet.Length]); diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Json/JsonReportWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Json/JsonReportWriter.cs index 89182bc06..a81866398 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Json/JsonReportWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Json/JsonReportWriter.cs @@ -30,9 +30,11 @@ public ResultFormatInformation Format public void WriteStream(Stream stream, AnalyzeResponse response) { using (var streamWriter = new StreamWriter(stream)) - using (var writer = new JsonTextWriter(streamWriter)) { - DataExtensions.Serializer.Serialize(writer, response); + using (var writer = new JsonTextWriter(streamWriter)) + { + DataExtensions.Serializer.Serialize(writer, response); + } } } } diff --git a/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs b/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs index e52966f85..1576ab8ba 100644 --- a/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs +++ b/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs @@ -205,7 +205,9 @@ private static bool IsSupportedAcrossTargets(IApiCatalogLookup catalog, string m public IEnumerable FindUnreferencedAssemblies(IEnumerable unreferencedAssemblies, IEnumerable specifiedUserAssemblies) { if (unreferencedAssemblies == null) + { yield break; + } // Find the unreferenced assemblies that are not framework assemblies. var userUnreferencedAssemblies = unreferencedAssemblies.AsParallel(). @@ -217,11 +219,15 @@ public IEnumerable FindUnreferencedAssemblies(IEnumerable unrefe { // if somehow a null made it through... if (userAsm == null) + { continue; + } // If the unresolved assembly was not actually specified, we need to tell the user that. if (specifiedUserAssemblies != null && specifiedUserAssemblies.Any(ua => ua != null && StringComparer.OrdinalIgnoreCase.Equals(ua.AssemblyIdentity, userAsm))) + { continue; + } yield return userAsm; } diff --git a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs index 263480693..b54de48a8 100644 --- a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs +++ b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs @@ -53,7 +53,9 @@ public static IEnumerable FromMarkdown(Stream stream) /// Parses markdown files into BrekaingChange objects /// /// The markdown to parse - /// Valid category strings. Pass null to allow any category. A breaking change using an invalid category will throw an exception while parsing the breaking change. + /// Valid category strings. Pass null + /// to allow any category. A breaking change using an invalid category + /// will throw an exception while parsing the breaking change. /// BreakingChanges parsed from the markdown public static IEnumerable FromMarkdown(Stream stream, IEnumerable allowedCategories) { @@ -266,7 +268,11 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState case ParseState.AffectedAPIs: // Trim md list and code markers, as well as comment tags (in case the affected APIs section is followed by a comment) string api = currentLine.Trim().TrimStart('*', '-', '`', ' ', '\t', '<', '!', '-').TrimEnd('`'); - if (string.IsNullOrWhiteSpace(api)) return; + if (string.IsNullOrWhiteSpace(api)) + { + return; + } + if (currentBreak.ApplicableApis == null) { currentBreak.ApplicableApis = new List(); @@ -352,9 +358,20 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState private static void CleanAndAddBreak(List breakingChanges, BreakingChange currentBreak) { // Clean up trailing white-space, etc. from long-form text entries - if (currentBreak.Details != null) currentBreak.Details = currentBreak.Details.Trim(); - if (currentBreak.Suggestion != null) currentBreak.Suggestion = currentBreak.Suggestion.Trim(); - if (currentBreak.Notes != null) currentBreak.Notes = currentBreak.Notes.Trim(); + if (currentBreak.Details != null) + { + currentBreak.Details = currentBreak.Details.Trim(); + } + + if (currentBreak.Suggestion != null) + { + currentBreak.Suggestion = currentBreak.Suggestion.Trim(); + } + + if (currentBreak.Notes != null) + { + currentBreak.Notes = currentBreak.Notes.Trim(); + } breakingChanges.Add(currentBreak); } diff --git a/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs b/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs index 7bd22ef60..90caf3bd4 100644 --- a/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs +++ b/src/lib/Microsoft.Fx.Portability/CompressedHttpClient.cs @@ -30,7 +30,8 @@ internal class CompressedHttpClient : HttpClient /// Product name that will be displayed in the User Agent string of requests /// Product version that will be displayed in the User Agent string of requests public CompressedHttpClient(ProductInformation info) - : this(info, new HttpClientHandler { + : this(info, new HttpClientHandler + { #if !FEATURE_SERVICE_POINT_MANAGER SslProtocols = SupportedSSLProtocols, #endif diff --git a/src/lib/Microsoft.Fx.Portability/DataExtensions.cs b/src/lib/Microsoft.Fx.Portability/DataExtensions.cs index 658c3bed7..b06160d2f 100644 --- a/src/lib/Microsoft.Fx.Portability/DataExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability/DataExtensions.cs @@ -36,11 +36,13 @@ public static byte[] Serialize(this T data) using (var outputStream = new MemoryStream()) { using (var writer = new StreamWriter(outputStream)) - using (var jsonWriter = new JsonTextWriter(writer)) { - var serializer = JsonSerializer.Create(JsonSettings); - serializer.Formatting = Formatting.None; - serializer.Serialize(jsonWriter, data); + using (var jsonWriter = new JsonTextWriter(writer)) + { + var serializer = JsonSerializer.Create(JsonSettings); + serializer.Formatting = Formatting.None; + serializer.Serialize(jsonWriter, data); + } } return outputStream.ToArray(); @@ -50,20 +52,24 @@ public static byte[] Serialize(this T data) public static byte[] SerializeAndCompress(this T data) { using (var jsonSerializedStream = new MemoryStream()) - using (var writer = new StreamWriter(jsonSerializedStream)) - using (var jsonWriter = new JsonTextWriter(writer)) { - Serializer.Serialize(jsonWriter, data); - jsonWriter.Flush(); - - using (var outputStream = new MemoryStream()) + using (var writer = new StreamWriter(jsonSerializedStream)) { - using (var compressStream = new GZipStream(outputStream, CompressionMode.Compress)) + using (var jsonWriter = new JsonTextWriter(writer)) { - jsonSerializedStream.WriteTo(compressStream); + Serializer.Serialize(jsonWriter, data); + jsonWriter.Flush(); + + using (var outputStream = new MemoryStream()) + { + using (var compressStream = new GZipStream(outputStream, CompressionMode.Compress)) + { + jsonSerializedStream.WriteTo(compressStream); + } + + return outputStream.ToArray(); + } } - - return outputStream.ToArray(); } } } @@ -120,15 +126,17 @@ public static byte[] Compress(this byte[] data) public static async Task CompressAsync(this Stream inputStream, Stream outputStream, bool leaveOpen) { using (var reader = new BinaryReader(inputStream, DefaultEncoding, leaveOpen)) - using (var compressionStream = new GZipStream(outputStream, CompressionMode.Compress, leaveOpen)) { - reader.BaseStream.Seek(0, SeekOrigin.Begin); - - while (reader.BaseStream.Position < reader.BaseStream.Length) + using (var compressionStream = new GZipStream(outputStream, CompressionMode.Compress, leaveOpen)) { - var buffer = reader.ReadBytes(DefaultBufferSize); + reader.BaseStream.Seek(0, SeekOrigin.Begin); + + while (reader.BaseStream.Position < reader.BaseStream.Length) + { + var buffer = reader.ReadBytes(DefaultBufferSize); - await compressionStream.WriteAsync(buffer, 0, buffer.Length); + await compressionStream.WriteAsync(buffer, 0, buffer.Length); + } } } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs index ac57caff6..43a61d3de 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/AssemblyInfo.cs @@ -69,7 +69,9 @@ public override bool Equals(object obj) { AssemblyInfo other = obj as AssemblyInfo; if (other == null) + { return false; + } return StringComparer.Ordinal.Equals(other.AssemblyIdentity, AssemblyIdentity) && StringComparer.Ordinal.Equals(other.TargetFrameworkMoniker, TargetFrameworkMoniker); diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/CloudApiCatalogLookup.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/CloudApiCatalogLookup.cs index daf5e5ac9..1bd55e66e 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/CloudApiCatalogLookup.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/CloudApiCatalogLookup.cs @@ -101,10 +101,14 @@ public virtual bool IsMemberInTarget(string docId, FrameworkName targetName, out // - The entry for the API contains the target. // - The version for when the API was introduced is before (or equal) to the target version. if (!_apiMapping.TryGetValue(docId, out var targets)) + { return false; + } if (!targets.TryGetValue(targetName.Identifier, out introducedVersion)) + { return false; + } return targetName.Version >= introducedVersion; } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfo.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfo.cs index 6ef1b2f00..c26c4cc43 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/IgnoreAssemblyInfo.cs @@ -48,7 +48,10 @@ public bool Equals(IgnoreAssemblyInfo other) var sortedOtherTargetsEnum = other.TargetsIgnored.OrderBy(s => s).GetEnumerator(); while (sortedTargetsEnum.MoveNext() && sortedOtherTargetsEnum.MoveNext()) { - if (!sortedTargetsEnum.Current.Equals(sortedOtherTargetsEnum.Current, StringComparison.OrdinalIgnoreCase)) return false; + if (!sortedTargetsEnum.Current.Equals(sortedOtherTargetsEnum.Current, StringComparison.OrdinalIgnoreCase)) + { + return false; + } } } diff --git a/src/lib/Microsoft.Fx.Portability/ObjectModel/ProjectSubmission.cs b/src/lib/Microsoft.Fx.Portability/ObjectModel/ProjectSubmission.cs index bc2f9f41f..7aee6e667 100644 --- a/src/lib/Microsoft.Fx.Portability/ObjectModel/ProjectSubmission.cs +++ b/src/lib/Microsoft.Fx.Portability/ObjectModel/ProjectSubmission.cs @@ -17,7 +17,10 @@ public override bool Equals(object obj) { var other = obj as ProjectSubmission; - if (other == null) return false; + if (other == null) + { + return false; + } return string.Equals(Name, other.Name, StringComparison.Ordinal) && SubmittedDate == other.SubmittedDate diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs index a7b4facae..8150ba3c3 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/MissingTypeInfo.cs @@ -55,7 +55,9 @@ public MissingTypeInfo(AssemblyInfo sourceAssembly, string docId, List { int pos = DocId.IndexOf("T:", StringComparison.Ordinal); if (pos == -1) + { throw new ArgumentException(LocalizedStrings.MemberShouldBeDefinedOnTypeException, nameof(docId)); + } TypeName = DocId.Substring(pos); MissingMembers = new HashSet(); diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs index f19069422..52ddc3942 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ObjectModel/TargetUsageInfo.cs @@ -30,7 +30,9 @@ public double PortabilityIndex { // prevent Div/0 if (_callsToAvailableAPIs == 0 && _callsToUnavailableAPIs == 0) + { return 0; + } return (double)_callsToAvailableAPIs / ((double)_callsToAvailableAPIs + _callsToUnavailableAPIs); } diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ReportFileWriter.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ReportFileWriter.cs index 3eb5ad001..353053d3e 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ReportFileWriter.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ReportFileWriter.cs @@ -23,12 +23,16 @@ public ReportFileWriter(IFileSystem fileSystem, IProgressReporter progressReport public async Task WriteReportAsync(byte[] report, string extension, string outputDirectory, string reportFileName, bool overwrite) { if (report == null || report.Length == 0) + { return null; + } var filename = GetFileName(outputDirectory, reportFileName, extension, isUnique: !overwrite); if (string.IsNullOrEmpty(filename)) + { return null; + } var filePath = _fileSystem.CombinePaths(outputDirectory, filename); var isWritten = await TryWriteReportAsync(report, filePath); @@ -46,9 +50,11 @@ private async Task TryWriteReportAsync(byte[] report, string filePath) try { using (var destinationStream = _fileSystem.CreateFile(filePath)) - using (var memoryStream = new MemoryStream(report)) { - await memoryStream.CopyToAsync(destinationStream); + using (var memoryStream = new MemoryStream(report)) + { + await memoryStream.CopyToAsync(destinationStream); + } } } catch (IOException ex) diff --git a/src/lib/Microsoft.Fx.Portability/Reporting/ReportGenerator.cs b/src/lib/Microsoft.Fx.Portability/Reporting/ReportGenerator.cs index 624260f7d..20880b666 100644 --- a/src/lib/Microsoft.Fx.Portability/Reporting/ReportGenerator.cs +++ b/src/lib/Microsoft.Fx.Portability/Reporting/ReportGenerator.cs @@ -41,9 +41,10 @@ public ReportingResult ComputeReport( } else { - ICollection calledIn; - if (!allDependencies.TryGetValue(item, out calledIn)) + if (!allDependencies.TryGetValue(item, out var calledIn)) + { return; + } foreach (var callingAsm in calledIn) { @@ -99,9 +100,10 @@ private static List ComputePerAssemblyUsage( // This is declared here to minimize allocations AssemblyUsageInfo currentAssembly; - ICollection usedIn; - if (!allDependencies.TryGetValue(memberInfo, out usedIn)) + if (!allDependencies.TryGetValue(memberInfo, out var usedIn)) + { return; + } foreach (var file in usedIn) { diff --git a/src/lib/Microsoft.Fx.Portability/TargetMapper.cs b/src/lib/Microsoft.Fx.Portability/TargetMapper.cs index 949c7fa2f..d63dbd9f3 100644 --- a/src/lib/Microsoft.Fx.Portability/TargetMapper.cs +++ b/src/lib/Microsoft.Fx.Portability/TargetMapper.cs @@ -196,10 +196,9 @@ public IEnumerable GetTargetNames(IEnumerable targets, bo */ if (group.Count() == 1) { - if (includeVersion) - yield return group.Single().FullName; - else - yield return group.Key; + yield return includeVersion + ? group.Single().FullName + : group.Key; } else { diff --git a/tests/ApiPort/ApiPortVS.Tests/TargetPlatformTests.cs b/tests/ApiPort/ApiPortVS.Tests/TargetPlatformTests.cs index d58ad3e5b..32a1772f7 100644 --- a/tests/ApiPort/ApiPortVS.Tests/TargetPlatformTests.cs +++ b/tests/ApiPort/ApiPortVS.Tests/TargetPlatformTests.cs @@ -17,7 +17,8 @@ public void TestAreEqual() var platform = new TargetPlatform { Name = frameworkName, - Versions = new[] { + Versions = new[] + { new TargetPlatformVersion { Version = new Version("1.0"), PlatformName = frameworkName }, new TargetPlatformVersion { Version = new Version("5.8.3"), PlatformName = frameworkName }, }.OrderBy(x => x.Version).ToList() @@ -26,7 +27,8 @@ public void TestAreEqual() var compared = new TargetPlatform { Name = frameworkName, - Versions = new[] { + Versions = new[] + { new TargetPlatformVersion { Version = new Version("1.0"), PlatformName = frameworkName }, new TargetPlatformVersion { Version = new Version("5.8.3"), PlatformName = frameworkName }, }.OrderBy(x => x.Version).ToList() @@ -45,7 +47,8 @@ public void AreNotEqual_DifferentName() var platform = new TargetPlatform { Name = name1, - Versions = new[] { + Versions = new[] + { new TargetPlatformVersion { Version = new Version("1.0"), PlatformName = name1 }, new TargetPlatformVersion { Version = new Version("5.8.3"), PlatformName = name1 }, }.OrderBy(x => x.Version).ToList() @@ -55,7 +58,8 @@ public void AreNotEqual_DifferentName() var compared = new TargetPlatform { Name = name2, - Versions = new[] { + Versions = new[] + { new TargetPlatformVersion { Version = new Version("1.0"), PlatformName = name2 }, new TargetPlatformVersion { Version = new Version("5.8.3"), PlatformName = name2 }, }.OrderBy(x => x.Version).ToList() @@ -75,7 +79,8 @@ public void AreNotEqual_DifferentVersionCount() var platform = new TargetPlatform { Name = name1, - Versions = new[] { + Versions = new[] + { new TargetPlatformVersion { Version = new Version("1.0"), PlatformName = name1 }, new TargetPlatformVersion { Version = new Version("5.8.3"), PlatformName = name1 }, }.OrderBy(x => x.Version).ToList() @@ -84,7 +89,8 @@ public void AreNotEqual_DifferentVersionCount() var compared = new TargetPlatform { Name = name1, - Versions = new[] { + Versions = new[] + { new TargetPlatformVersion { Version = new Version("2.8"), PlatformName = name1 }, new TargetPlatformVersion { Version = new Version("1.0"), PlatformName = name1 }, new TargetPlatformVersion { Version = new Version("5.8.3"), PlatformName = name1 }, @@ -106,7 +112,8 @@ public void AreNotEqual_DifferentVersionNumbers() var platform = new TargetPlatform { Name = name1, - Versions = new[] { + Versions = new[] + { new TargetPlatformVersion { Version = new Version("1.0"), PlatformName = name1 }, new TargetPlatformVersion { Version = new Version("5.8.3"), PlatformName = name1 }, }.OrderBy(x => x.Version).ToList() @@ -115,7 +122,8 @@ public void AreNotEqual_DifferentVersionNumbers() var compared = new TargetPlatform { Name = name1, - Versions = new[] { + Versions = new[] + { new TargetPlatformVersion { Version = new Version("1.0"), PlatformName = name1 }, new TargetPlatformVersion { Version = new Version("5.7.3"), PlatformName = name1 }, }.OrderBy(x => x.Version).ToList() diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs index e3c262a41..38f1fdd6c 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs @@ -74,10 +74,12 @@ private static string GetText(string fileName) var name = typeof(TestAssembly).GetTypeInfo().Assembly.GetManifestResourceNames().Single(n => n.EndsWith(fileName, StringComparison.Ordinal)); using (var stream = typeof(TestAssembly).GetTypeInfo().Assembly.GetManifestResourceStream(name)) - using (var reader = new StreamReader(stream)) + { + using (var reader = new StreamReader(stream)) { return reader.ReadToEnd(); } + } } } } diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs index 4a17aa693..24c2c00d3 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs @@ -104,7 +104,8 @@ public void VerifyDotNetFrameworkFilter() var assemblyToTest = TestAssembly.Create("FilterApis.cs", _output); var expected = FilterApisDocIds - .Concat(new[] { + .Concat(new[] + { "M:System.Uri.TryCreate(System.String,System.UriKind,System.Uri@)", "T:System.Uri", "T:System.UriKind" diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs index c532cbefb..c5b73b7df 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs @@ -25,15 +25,17 @@ public void MultipleMscorlibReferencesFound() var file = TestAssembly.Create("multiple-mscorlib.il", _output); using (var stream = file.OpenRead()) - using (var peFile = new PEReader(stream)) { - var metadataReader = peFile.GetMetadataReader(); + using (var peFile = new PEReader(stream)) + { + var metadataReader = peFile.GetMetadataReader(); - Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); - Assert.Equal("mscorlib", assemblyInfo.Name); - Assert.Equal("4.0.0.0", assemblyInfo.Version.ToString()); - Assert.Equal("neutral", assemblyInfo.Culture); - Assert.Equal("b77a5c561934e089", assemblyInfo.PublicKeyToken); + Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); + Assert.Equal("mscorlib", assemblyInfo.Name); + Assert.Equal("4.0.0.0", assemblyInfo.Version.ToString()); + Assert.Equal("neutral", assemblyInfo.Culture); + Assert.Equal("b77a5c561934e089", assemblyInfo.PublicKeyToken); + } } } @@ -48,15 +50,17 @@ public void NetstandardReferencesOnly() var file = TestAssembly.Create("OnlyNetStandardReference.il", _output); using (var stream = file.OpenRead()) - using (var peFile = new PEReader(stream)) { - var metadataReader = peFile.GetMetadataReader(); + using (var peFile = new PEReader(stream)) + { + var metadataReader = peFile.GetMetadataReader(); - Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); - Assert.Equal("netstandard", assemblyInfo.Name); - Assert.Equal("2.0.0.0", assemblyInfo.Version.ToString()); - Assert.Equal("neutral", assemblyInfo.Culture); - Assert.Equal("cc7b13ffcd2ddd51", assemblyInfo.PublicKeyToken); + Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); + Assert.Equal("netstandard", assemblyInfo.Name); + Assert.Equal("2.0.0.0", assemblyInfo.Version.ToString()); + Assert.Equal("neutral", assemblyInfo.Culture); + Assert.Equal("cc7b13ffcd2ddd51", assemblyInfo.PublicKeyToken); + } } } @@ -73,12 +77,14 @@ public void ResourceAssembliesGetSkipped() var file = TestAssembly.Create("ResourceAssembliesGetSkipped_NoReferences.il", _output); using (var stream = file.OpenRead()) - using (var peFile = new PEReader(stream)) { - var metadataReader = peFile.GetMetadataReader(); + using (var peFile = new PEReader(stream)) + { + var metadataReader = peFile.GetMetadataReader(); - Assert.False(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); - Assert.Null(assemblyInfo); + Assert.False(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); + Assert.Null(assemblyInfo); + } } } @@ -98,12 +104,14 @@ public void LookInFilePassedInAssembly(string name) var file = TestAssembly.CreateFromIL(source, name, _output); using (var stream = file.OpenRead()) - using (var peFile = new PEReader(stream)) { - var metadataReader = peFile.GetMetadataReader(); + using (var peFile = new PEReader(stream)) + { + var metadataReader = peFile.GetMetadataReader(); - Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); - Assert.Equal(name, assemblyInfo.Name); + Assert.True(objectFinder.TryGetSystemRuntimeAssemblyInformation(metadataReader, out var assemblyInfo)); + Assert.Equal(name, assemblyInfo.Name); + } } } } diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs index 36506d9f3..a565d205a 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs @@ -182,9 +182,11 @@ public Stream OpenRead() var ilPath = Path.GetTempFileName(); using (var fs = File.OpenWrite(ilPath)) - using (var stream = _other.OpenRead()) { - stream.CopyTo(fs); + using (var stream = _other.OpenRead()) + { + stream.CopyTo(fs); + } } var psi = new ProcessStartInfo diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs index 9103f5af4..bd083225f 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs @@ -101,7 +101,8 @@ public void IdInComments() Suggestion = "Be aware that Application.FilterMessage will no longer throw for the re-entrant IMessageFilter.PreFilterMessage behavior described above. This only affects applications targeting the .NET Framework 4.6.1.", Categories = new List { "Windows Forms" }, Link = "https://msdn.microsoft.com/en-us/library/mt620031%28v=vs.110%29.aspx#WinForms", - ApplicableApis = new List { + ApplicableApis = new List + { "M:System.Windows.Forms.Application.FilterMessage(System.Windows.Forms.Message@)" }, Notes = "It's unclear if this one will be better analyzed by Application.FilterMessage callers (who would have seen the exception previously)" @@ -290,7 +291,8 @@ private Stream GetBreakingChangeMarkdown(string resourceName) IsBuildTime = false, SourceAnalyzerStatus = BreakingChangeAnalyzerStatus.Available, Suggestion = "If the old .NET 4.0 URI parsing semantics are necessary (they often aren't), they can be used by targeting .NET 4.0. This can be accomplished by using a TargetFrameworkAttribute on the assembly, or through Visual Studio's project system UI in the 'project properties' page.", - ApplicableApis = new[] { + ApplicableApis = new[] + { "M:System.Uri.#ctor(System.String)", "M:System.Uri.#ctor(System.String,System.Boolean)", "M:System.Uri.#ctor(System.String,System.UriKind)", diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/IgnoreAssemblyInfoTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/IgnoreAssemblyInfoTests.cs index 115c86416..78e54b9e1 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/IgnoreAssemblyInfoTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ObjectModel/IgnoreAssemblyInfoTests.cs @@ -8,24 +8,28 @@ namespace Microsoft.Fx.Portability.Tests.ObjectModel { public class IgnoreAssemblyInfoTests { - private readonly IgnoreAssemblyInfo[] _set1 = new[] { + private readonly IgnoreAssemblyInfo[] _set1 = new[] + { new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new[] { "v1", "v2" } }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar", TargetsIgnored = new[] { "v2" } } }; - private readonly IgnoreAssemblyInfo[] _set2 = new[] { + private readonly IgnoreAssemblyInfo[] _set2 = new[] + { new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new[] { "v1", "v3" } }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar", TargetsIgnored = new[] { "v1" } }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Baz", TargetsIgnored = new string[0] } }; - private readonly IgnoreAssemblyInfo[] _set3 = new[] { + private readonly IgnoreAssemblyInfo[] _set3 = new[] + { new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new[] { "V1" } }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar" }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Baz", TargetsIgnored = new[] { "v1" } } }; - private readonly IgnoreAssemblyInfo[] _combined = new[] { + private readonly IgnoreAssemblyInfo[] _combined = new[] + { new IgnoreAssemblyInfo() { AssemblyIdentity = "Foo", TargetsIgnored = new[] { "v1", "v2", "v3" } }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Bar" }, new IgnoreAssemblyInfo() { AssemblyIdentity = "Baz" } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/ReportFileWriterTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/ReportFileWriterTests.cs index af6dd4939..fbe63f1e2 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/ReportFileWriterTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/ReportFileWriterTests.cs @@ -89,7 +89,8 @@ public static async Task UniquelyNamedFileStream_NumberedFileExists_IncrementsNu fileSystem.FileExists(path).Returns(true); var nextFileName = string.Format(CultureInfo.CurrentCulture, fileNameFormat, fileNumber); path = Path.Combine(dir, Path.ChangeExtension(nextFileName, extension)); - } while (fileNumber++ < FileExistsCount); + } + while (fileNumber++ < FileExistsCount); var writer = new ReportFileWriter(fileSystem, progressReporter); var report = Encoding.UTF8.GetBytes("This is a test report."); diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs index 67eca5039..e6a1bdf4e 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TargetMapTests.cs @@ -209,9 +209,11 @@ public static void LoadXmlFromDefault() try { using (var fs = file.OpenWrite()) - using (var writer = new StreamWriter(fs)) { - writer.Write(xml); + using (var writer = new StreamWriter(fs)) + { + writer.Write(xml); + } } var map = new TargetMapper(); @@ -427,17 +429,21 @@ public static void GetTargetNamesForMultipleTargetVersions() var targetNamesWithVersions = mapper.GetTargetNames(targets, includeVersion: true).ToArray(); AreCollectionsEqual( - new string[] { + new string[] + { netFramework4.FullName, windows81.FullName, netFramework451.FullName, "Windows Phone", - windows8.FullName }, + windows8.FullName + }, targetNames); AreCollectionsEqual( - new string[] { + new string[] + { netFramework4.FullName, windows81.FullName, netFramework451.FullName, windowsPhone.FullName, - windows8.FullName }, + windows8.FullName + }, targetNamesWithVersions); } @@ -452,14 +458,16 @@ private static void AreCollectionsEqual(IEnumerable expected, IEnumerable< private static TargetMapper LoadXml(string config) { using (var ms = new MemoryStream()) - using (var writer = new StreamWriter(ms) { AutoFlush = true }) { - writer.Write(config); - ms.Seek(0, SeekOrigin.Begin); + using (var writer = new StreamWriter(ms) { AutoFlush = true }) + { + writer.Write(config); + ms.Seek(0, SeekOrigin.Begin); - var targetMapper = new TargetMapper(); - targetMapper.Load(ms); - return targetMapper; + var targetMapper = new TargetMapper(); + targetMapper.Load(ms); + return targetMapper; + } } } } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs index d77360734..046c71167 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestCatalog.cs @@ -62,25 +62,21 @@ public IEnumerable GetPublicTargets() public Version GetVersionIntroducedIn(string docId, FrameworkName target) { if (docId == DocId1) + { return Target1.Version; + } return null; } public bool IsFrameworkAssembly(string assemblyIdentity) { - if (assemblyIdentity == "mscorlib") - return true; - - return false; + return assemblyIdentity == "mscorlib"; } public bool IsFrameworkMember(string docId) { - if (docId == DocId1) - return true; - - return false; + return docId == DocId1; } public bool IsMemberInTarget(string docId, FrameworkName targetName, out Version introducedVersion) diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestDotNetCatalog.cs b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestDotNetCatalog.cs index 9b9c2b412..7d8b22696 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestDotNetCatalog.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/TestData/TestDotNetCatalog.cs @@ -10,13 +10,15 @@ namespace Microsoft.Fx.Portability.Tests.TestData { public class TestDotNetCatalog : DotNetCatalog { - private static readonly string[] FrameworkIdentities = new[] { + private static readonly string[] FrameworkIdentities = new[] + { "System.Collections, PublicKeyToken=b03f5f7f11d50a3a", "System.Collections.Concurrent, PublicKeyToken=b03f5f7f11d50a3a", "System.Collections.NonGeneric, PublicKeyToken=b03f5f7f11d50a3a" }; - private static readonly TargetInfo[] TestSupportedTargets = new[] { + private static readonly TargetInfo[] TestSupportedTargets = new[] + { new TargetInfo { DisplayName = Windows80, IsReleased = true }, new TargetInfo { DisplayName = Windows81, IsReleased = true }, new TargetInfo { DisplayName = NetCore50, IsReleased = true }, @@ -40,8 +42,10 @@ private ApiInfoStorage[] GetApis() var targets11 = new[] { Windows80, NetCore50, Net11 }; var targets40 = new[] { Windows80, NetCore50, Net40, NetStandard16 }; - var apis = new[] { - new ApiInfoStorage { + var apis = new[] + { + new ApiInfoStorage + { DocId = "N:System.Collections", FullName = "System.Collections", Name = "System.Collections", @@ -49,7 +53,8 @@ private ApiInfoStorage[] GetApis() Parent = null, Targets = targets11 }, - new ApiInfoStorage { + new ApiInfoStorage + { DocId = "N:System.Collections.Concurrent", FullName = "System.Collections.Concurrent", Name = "System.Collections.Concurrent", @@ -57,7 +62,8 @@ private ApiInfoStorage[] GetApis() Parent = null, Targets = targets40 }, - new ApiInfoStorage { + new ApiInfoStorage + { DocId = "T:System.Collections.Concurrent.ConcurrentBag`1", FullName = "System.Collections.Concurrent.ConcurrentBag", Name = "ConcurrentBag", @@ -65,7 +71,8 @@ private ApiInfoStorage[] GetApis() Parent = "N:System.Collections.Concurrent", Targets = targets40 }, - new ApiInfoStorage { + new ApiInfoStorage + { DocId = "P:System.Collections.Concurrent.ConcurrentBag`1.Count", FullName = "System.Collections.Concurrent.ConcurrentBag.Count", Name = "Count", @@ -73,7 +80,8 @@ private ApiInfoStorage[] GetApis() Parent = "T:System.Collections.Concurrent.ConcurrentBag`1", Targets = targets40 }, - new ApiInfoStorage { + new ApiInfoStorage + { DocId = "M:System.Collections.Concurrent.ConcurrentBag`1.CopyTo(`0[],System.Int32)", FullName = "System.Collections.Concurrent.ConcurrentBag.CopyTo(T[], Int32)", Name = "CopyTo(T[], Int32)", @@ -81,7 +89,8 @@ private ApiInfoStorage[] GetApis() Parent = "T:System.Collections.Concurrent.ConcurrentBag`1", Targets = targets40 }, - new ApiInfoStorage { + new ApiInfoStorage + { DocId = "M:System.Collections.Concurrent.ConcurrentBag`1.get_Count", FullName = "System.Collections.Concurrent.ConcurrentBag.Count.get_Count()", Name = "get_Count()", From a85785230fb76d34a0fc63557297a7c67c3a005b Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Fri, 28 Sep 2018 14:52:21 -0700 Subject: [PATCH 13/17] More style cop rule fixes. Part 6 (#713) * Unsuppress SA1504 - SA1510 * Fixing SA1504 - SA1510 * Unsuppressing SA1511 - SA1520 * Fixing SA1512 issues * Fixing SA1513 * Fixing SA1515 * Unsuppressing SA1601 - SA1605 * Unsuppress SA1606 - SA1610 --- rules.ruleset | 24 +------------------ .../ComProjectMapper.cs | 1 + .../SourceMapping/CciMetadataTraverser.cs | 1 - .../ApiPort/ConsoleProgressReporter.cs | 1 + src/ApiPort/ApiPort/Program.cs | 1 + .../Proxy/ConsoleCredentialProvider.cs | 3 +++ src/ApiPort/ApiPort/Proxy/ProxyProvider.cs | 1 + .../Analyzer/DependencyFinderEngine.cs | 3 ++- .../DependencyFinderEngineHelper.cs | 1 + .../MemberMetadataInfoTypeProvider.cs | 6 +++-- .../ReflectionMetadataDependencyInfo.cs | 1 + .../Microsoft.Fx.Portability.Offline/Data.cs | 6 ++++- .../ExcelOpenXmlOutputWriter.cs | 5 +++- .../OpenXmlExtensions.cs | 3 +-- .../RazorHtmlObject.cs | 4 +++- .../Analysis/AnalysisEngine.cs | 3 ++- .../Analysis/TargetNameParser.cs | 2 +- .../Analyzer/RequestAnalyzer.cs | 1 + .../Microsoft.Fx.Portability/ApiPortClient.cs | 20 +++++++++------- .../BreakingChangeParser.cs | 14 +++++++++++ .../CompressedHttpClient.cs | 1 + .../ObjectModel/AssemblyInfo.cs | 14 +++++++---- .../ObjectModel/CloudApiCatalogLookup.cs | 2 ++ .../ObjectModel/IgnoreAssemblyInfo.cs | 1 + .../ObjectModel/IgnoreAssemblyInfoList.cs | 1 + .../ObjectModel/NuGetPackageInfo.cs | 3 +++ .../ObjectModel/NuGetPackageInfoComparer.cs | 2 ++ .../ApiPortVS.Tests/TargetPlatformTests.cs | 1 - .../AnalysisEngineNuGetPackageInfoTests.cs | 1 + .../Analyzer/DotNetFrameworkFilterTests.cs | 2 ++ .../BreakingChangeParserTests.cs | 2 +- .../UrlBuilderTest.cs | 1 - 32 files changed, 82 insertions(+), 50 deletions(-) diff --git a/rules.ruleset b/rules.ruleset index d685d3995..65a7bc961 100644 --- a/rules.ruleset +++ b/rules.ruleset @@ -61,30 +61,8 @@ - - - - - - - - - - - - - - + - - - - - - - - - diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/ComProjectMapper.cs b/src/ApiPort/ApiPort.VisualStudio.Common/ComProjectMapper.cs index fdfa69c10..b6e49b499 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/ComProjectMapper.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/ComProjectMapper.cs @@ -79,6 +79,7 @@ public async Task GetVsProjectConfigurationAsync(Project project) Trace.TraceError(ToCurrentCulture($"Could not retrieve {nameof(IVsCfgProvider)} from project: {project.Name}")); return null; } + if (!(provider is IVsCfgProvider2)) { Trace.TraceError(ToCurrentCulture($"IVsCfgProvider returned {provider.GetType()} is not of the right type. Expected: {nameof(IVsCfgProvider2)}")); diff --git a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciMetadataTraverser.cs b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciMetadataTraverser.cs index 5687c58ee..9f808829b 100644 --- a/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciMetadataTraverser.cs +++ b/src/ApiPort/ApiPort.VisualStudio.Common/SourceMapping/CciMetadataTraverser.cs @@ -52,7 +52,6 @@ from member in type.MissingMembers // public class Foo {} // // The 'Serializable' (Which is not supported on most platforms) is not found - public override void Visit(IMethodBody method) { var calls = method.Operations diff --git a/src/ApiPort/ApiPort/ConsoleProgressReporter.cs b/src/ApiPort/ApiPort/ConsoleProgressReporter.cs index 2676b1aa5..9985f5649 100644 --- a/src/ApiPort/ApiPort/ConsoleProgressReporter.cs +++ b/src/ApiPort/ApiPort/ConsoleProgressReporter.cs @@ -161,6 +161,7 @@ public void SuspendAnimation() { return; } + _animationResetEvent.Reset(); } diff --git a/src/ApiPort/ApiPort/Program.cs b/src/ApiPort/ApiPort/Program.cs index 0727e06a3..0ac991e93 100644 --- a/src/ApiPort/ApiPort/Program.cs +++ b/src/ApiPort/ApiPort/Program.cs @@ -154,6 +154,7 @@ private static IEnumerable GetRecursiveInnerExceptions(Exception ex) } } } + // Other exceptions can have only one inner exception else { diff --git a/src/ApiPort/ApiPort/Proxy/ConsoleCredentialProvider.cs b/src/ApiPort/ApiPort/Proxy/ConsoleCredentialProvider.cs index 76b904ab8..c1bb6de3c 100644 --- a/src/ApiPort/ApiPort/Proxy/ConsoleCredentialProvider.cs +++ b/src/ApiPort/ApiPort/Proxy/ConsoleCredentialProvider.cs @@ -105,6 +105,7 @@ private static void ReadSecureStringFromConsole(SecureString secureString) { continue; } + Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); Console.Write(' '); Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); @@ -138,6 +139,7 @@ private static string ReadUnsecureStringFromConsole() { continue; } + Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); Console.Write(' '); Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); @@ -149,6 +151,7 @@ private static string ReadUnsecureStringFromConsole() Console.Write('*'); } } + Console.WriteLine(); return builder.ToString(); diff --git a/src/ApiPort/ApiPort/Proxy/ProxyProvider.cs b/src/ApiPort/ApiPort/Proxy/ProxyProvider.cs index d612fe37b..9d961b339 100644 --- a/src/ApiPort/ApiPort/Proxy/ProxyProvider.cs +++ b/src/ApiPort/ApiPort/Proxy/ProxyProvider.cs @@ -249,6 +249,7 @@ private static bool IsSystemProxySet(Uri uri) { return false; } + return !proxy.IsBypassed(uri); } } diff --git a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs index 41d5c59a0..9fe738f0d 100644 --- a/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs +++ b/src/lib/Microsoft.Fx.Portability.Cci/Analyzer/DependencyFinderEngine.cs @@ -119,7 +119,6 @@ private IEnumerable GetDependencies(string assemblyLocation) if (cciAssembly == null) { _assembliesWithError.Add(assemblyLocation); - // error. yield break; } @@ -146,6 +145,7 @@ private IEnumerable GetDependencies(string assemblyLocation) } string definedIn = reference.ContainingType.GetAssemblyReference().ContainingAssembly.AssemblyIdentity.Format(); + // return the type yield return new MemberDependency() { @@ -168,6 +168,7 @@ private IEnumerable GetDependencies(string assemblyLocation) foreach (var refence in cciAssembly.GetTypeReferences()) { string definedIn = refence.GetAssemblyReference().ContainingAssembly.AssemblyIdentity.Format(); + // return the type yield return new MemberDependency() { diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs index 96b6545bf..4b2188643 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs @@ -55,6 +55,7 @@ private IList ComputeAssemblyReferences(MetadataRe { } } + return refs; } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs index 68527077f..505064adc 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/MemberMetadataInfoTypeProvider.cs @@ -163,7 +163,8 @@ public MemberMetadataInfo GetFullName(TypeReference reference, TypeReference? ch throw new BadImageFormatException(LocalizedStrings.InfiniteTypeParentingRecursion); } } - MemberMetadataInfo info2 = GetFullName(Reader.GetTypeReference((TypeReferenceHandle)scope), reference); + + var info2 = GetFullName(Reader.GetTypeReference((TypeReferenceHandle)scope), reference); return new MemberMetadataInfo(name, info2); default: @@ -329,10 +330,11 @@ public MemberMetadataInfo GetGenericInstantiation(MemberMetadataInfo genericType { genericType.IsGenericInstance = true; genericType.GenericTypeArgs = new List(typeArguments); - foreach (MemberMetadataInfo mInfo in genericType.GenericTypeArgs) + foreach (var mInfo in genericType.GenericTypeArgs) { mInfo.IsEnclosedType = true; } + return genericType; } diff --git a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs index eefea5193..09524ce98 100644 --- a/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs +++ b/src/lib/Microsoft.Fx.Portability.MetadataReader/ReflectionMetadataDependencyInfo.cs @@ -141,6 +141,7 @@ private IEnumerable GetDependencies(IAssemblyFile file) { throw; } + // Occurs when we cannot find the System.Object assembly. if (exc is SystemObjectNotFoundException) { diff --git a/src/lib/Microsoft.Fx.Portability.Offline/Data.cs b/src/lib/Microsoft.Fx.Portability.Offline/Data.cs index cda44d39a..f5add39c9 100644 --- a/src/lib/Microsoft.Fx.Portability.Offline/Data.cs +++ b/src/lib/Microsoft.Fx.Portability.Offline/Data.cs @@ -5,7 +5,6 @@ using Microsoft.Fx.Portability.Offline.Resources; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -40,10 +39,12 @@ public static IEnumerable LoadBreakingChanges() return breakingChanges; } + // If no BreakingChanges folder exists, then we'll fall back to loading embedded breaking changes else { var breakingChanges = new List(); + // Breaking changes will be serialized as either md or (less commonly now) json files foreach (var file in typeof(Data).GetTypeInfo().Assembly.GetManifestResourceNames().Where(s => s.EndsWith(".md", StringComparison.OrdinalIgnoreCase) || s.EndsWith(".json", StringComparison.OrdinalIgnoreCase))) { @@ -77,6 +78,7 @@ private static IEnumerable GetLocalAllowedCategories() return categoriesFile.Deserialize(); } } + return null; } @@ -116,6 +118,7 @@ private static IEnumerable ParseBreakingChange(Stream stream, st { return BreakingChangeParser.FromMarkdown(stream, allowedCategories); } + if (string.Equals(".json", extension, StringComparison.OrdinalIgnoreCase)) { try @@ -127,6 +130,7 @@ private static IEnumerable ParseBreakingChange(Stream stream, st // An invalid json file will throw an exception when deserialized. Simply ignore such files. } } + return Enumerable.Empty(); } } diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs index 3787f2c3c..32b817d11 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/ExcelOpenXmlOutputWriter.cs @@ -140,10 +140,13 @@ private void GenerateSummaryPage(Worksheet summaryPage, ReportingResult analysis // 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(); @@ -393,6 +396,7 @@ private void GenerateNuGetInfoPage(Worksheet page, ReportingResult analysisResul { rowContent.Add(nugetInfo.AssemblyInfo); } + page.AddRow(rowContent.ToArray()); rowCount++; } @@ -454,6 +458,5 @@ private static object AddLink(string docId) }; #endif } - } } diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs b/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs index 066f9f9fe..df0e22a84 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Excel/OpenXmlExtensions.cs @@ -300,8 +300,7 @@ public static Cell CreateNumberCell(string value) private static string ComputeRange(int rowStart, int rowCount, int columnStart, int columnCount) { - // only support up to 26 columns for now.. - + // Only support up to 26 columns for now.. if (columnStart + columnCount > 26) { throw new NotSupportedException(LocalizedStrings.TooManyColumns); diff --git a/src/lib/Microsoft.Fx.Portability.Reports.Html/RazorHtmlObject.cs b/src/lib/Microsoft.Fx.Portability.Reports.Html/RazorHtmlObject.cs index e1ff37d1a..0e3e5efee 100644 --- a/src/lib/Microsoft.Fx.Portability.Reports.Html/RazorHtmlObject.cs +++ b/src/lib/Microsoft.Fx.Portability.Reports.Html/RazorHtmlObject.cs @@ -76,17 +76,19 @@ private static IOrderedEnumerable>> ret = new Dictionary>>(); - foreach (BreakingChangeDependency b in breakingChanges ?? Enumerable.Empty()) + foreach (var b in breakingChanges ?? Enumerable.Empty()) { // Add breaking changes, grouped by assembly, each with a collection of MemberInfos that trigger the break if (!ret.ContainsKey(b.DependantAssembly)) { ret.Add(b.DependantAssembly, new Dictionary>()); } + if (!ret[b.DependantAssembly].ContainsKey(b.Break)) { ret[b.DependantAssembly].Add(b.Break, new List()); } + if (!ret[b.DependantAssembly][b.Break].Contains(b.Member)) { (ret[b.DependantAssembly][b.Break] as IList).Add(b.Member); diff --git a/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs b/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs index 1576ab8ba..5584cceef 100644 --- a/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs +++ b/src/lib/Microsoft.Fx.Portability/Analysis/AnalysisEngine.cs @@ -143,7 +143,6 @@ public IList FindMembersNotInTargets(IEnumerable targ sw.Stop(); // Trace.TraceInformation("Computing members not in target took '{0}'", sw.Elapsed); - return missingMembers; } @@ -298,6 +297,7 @@ public IEnumerable ComputeAssembliesToRemove( break; } } + if (supportedOnAllTargets) { yield return assembly.AssemblyIdentity; @@ -318,6 +318,7 @@ public IDictionary> FilterDependencies(IDi filteredDependencies.Add(dependency.Key, newList.ToList()); } } + return filteredDependencies; } diff --git a/src/lib/Microsoft.Fx.Portability/Analysis/TargetNameParser.cs b/src/lib/Microsoft.Fx.Portability/Analysis/TargetNameParser.cs index a261e8c2f..dcbd7f06a 100644 --- a/src/lib/Microsoft.Fx.Portability/Analysis/TargetNameParser.cs +++ b/src/lib/Microsoft.Fx.Portability/Analysis/TargetNameParser.cs @@ -98,9 +98,9 @@ private ICollection ParseTargets(IEnumerable targets, boo { list.Add(_catalog.GetLatestVersion(target) ?? new FrameworkName(target)); } - // Catch ArgumentException because FrameworkName does not have a TryParse method catch (ArgumentException) { + // Catch ArgumentException because FrameworkName does not have a TryParse method if (!skipNonExistent) { throw new UnknownTargetException(target); diff --git a/src/lib/Microsoft.Fx.Portability/Analyzer/RequestAnalyzer.cs b/src/lib/Microsoft.Fx.Portability/Analyzer/RequestAnalyzer.cs index 8aa678df9..995d28cc9 100644 --- a/src/lib/Microsoft.Fx.Portability/Analyzer/RequestAnalyzer.cs +++ b/src/lib/Microsoft.Fx.Portability/Analyzer/RequestAnalyzer.cs @@ -67,6 +67,7 @@ public AnalyzeResponse AnalyzeRequest(AnalyzeRequest request, string submissionI var nugetPackagesForMissingAssemblies = _analysisEngine.GetNuGetPackagesInfoFromAssembly(missingUserAssemblies, targets); nugetPackages = nugetPackagesForMissingAssemblies.Union(nugetPackagesForUserAssemblies).ToList(); } + nugetPackages.Sort(new NuGetPackageInfoComparer()); userAssemblies.RemoveWhere(assembliesToRemove.Contains); diff --git a/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs b/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs index 3be4bb1a8..6596898c4 100644 --- a/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs +++ b/src/lib/Microsoft.Fx.Portability/ApiPortClient.cs @@ -283,15 +283,17 @@ private AnalyzeRequest GenerateRequest(IApiPortOptions options, IDependencyInfo { Targets = options.Targets.SelectMany(_targetMapper.GetNames).ToList(), Dependencies = dependencyInfo.Dependencies, - AssembliesToIgnore = _assembliesToIgnore, // We pass along assemblies to ignore instead of filtering them from Dependencies at this point - // because breaking change analysis and portability analysis will likely want to filter dependencies - // in different ways for ignored assemblies. - // For breaking changes, we should show breaking changes for - // an assembly if it is un-ignored on any of the user-specified targets and we should hide breaking changes - // for an assembly if it ignored on all user-specified targets. - // For portability analysis, on the other hand, we will want to show portability for precisely those targets - // that a user specifies that are not on the ignore list. In this case, some of the assembly's dependency - // information will be needed. + + // We pass along assemblies to ignore instead of filtering them from Dependencies at this point + // because breaking change analysis and portability analysis will likely want to filter dependencies + // in different ways for ignored assemblies. + // For breaking changes, we should show breaking changes for + // an assembly if it is un-ignored on any of the user-specified targets and we should hide breaking changes + // for an assembly if it ignored on all user-specified targets. + // For portability analysis, on the other hand, we will want to show portability for precisely those targets + // that a user specifies that are not on the ignore list. In this case, some of the assembly's dependency + // information will be needed. + AssembliesToIgnore = _assembliesToIgnore, UnresolvedAssemblies = dependencyInfo.UnresolvedAssemblies.Keys.ToList(), UnresolvedAssembliesDictionary = dependencyInfo.UnresolvedAssemblies, UserAssemblies = dependencyInfo.UserAssemblies.ToList(), diff --git a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs index b54de48a8..9b2edb41e 100644 --- a/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs +++ b/src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs @@ -79,6 +79,7 @@ public static IEnumerable FromMarkdown(Stream stream, IEnumerabl { CleanAndAddBreak(breakingChanges, currentBreak); } + currentBreak = new BreakingChange(); // Separate ID and title @@ -107,6 +108,7 @@ public static IEnumerable FromMarkdown(Stream stream, IEnumerabl // Clear state state = ParseState.None; } + // Only parse breaking change if we've seen a breaking change header ("## ...") else if (currentBreak != null) { @@ -243,6 +245,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.BugLink = currentLine.Trim(); } + break; case ParseState.Scope: BreakingChangeImpact scope; @@ -250,6 +253,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.ImpactScope = scope; } + break; case ParseState.VersionBroken: Version verBroken; @@ -257,6 +261,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.VersionBroken = verBroken; } + break; case ParseState.VersionFixed: Version verFixed; @@ -264,6 +269,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.VersionFixed = verFixed; } + break; case ParseState.AffectedAPIs: // Trim md list and code markers, as well as comment tags (in case the affected APIs section is followed by a comment) @@ -277,10 +283,12 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.ApplicableApis = new List(); } + if (!IgnoredApis.Contains(api)) { currentBreak.ApplicableApis.Add(api); } + break; case ParseState.Details: if (currentBreak.Details == null) @@ -291,6 +299,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.Details += "\n" + currentLine; } + break; case ParseState.Suggestion: if (currentBreak.Suggestion == null) @@ -301,6 +310,7 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.Suggestion += "\n" + currentLine; } + break; case ParseState.Notes: // Special-case the fact that 'notes' will often come at the end of a comment section and we don't need the closing --> in the note. @@ -317,12 +327,14 @@ private static void ParseNonStateChange(BreakingChange currentBreak, ParseState { currentBreak.Notes += "\n" + currentLine; } + break; case ParseState.SourceAnalyzerStatus: if (Enum.TryParse(currentLine.Trim().Replace(" ", string.Empty), true, out var status)) { currentBreak.SourceAnalyzerStatus = status; } + break; case ParseState.Categories: if (string.IsNullOrWhiteSpace(currentLine) || currentLine.StartsWith(" diff --git a/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs b/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs index ba2813cd8..ab21203d7 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs +++ b/src/ApiPort/ApiPort.VisualStudio/ApiPortVSPackage.cs @@ -11,23 +11,28 @@ using System.ComponentModel.Design; using System.Reflection; using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; namespace ApiPortVS { [Guid(Guids.ApiPortVSPkgString)] [InstalledProductRegistration("#110", "#112", "1.1.10808.0", IconResourceID = 400)] // Help->About info - [PackageRegistration(UseManagedResourcesOnly = true)] - [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)] // load when a solution is opened + [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)] + [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string, PackageAutoLoadFlags.BackgroundLoad)] // load when a solution is opened [ProvideMenuResource("Menus.ctmenu", 1)] [ProvideOptionPage(typeof(OptionsPage), ".NET Portability Analyzer", "General", 110, 113, true)] [ProvideToolWindow(typeof(AnalysisOutputToolWindow))] - public class ApiPortVSPackage : Package, IResultToolbar + [ProvideService(typeof(ApiPortVSPackage), IsAsyncQueryable = true)] + public class ApiPortVSPackage : AsyncPackage, IResultToolbar { private static ServiceProvider _serviceProvider; private readonly AssemblyRedirectResolver _assemblyResolver; internal static IServiceProvider LocalServiceProvider { get { return _serviceProvider; } } + internal static IAsyncServiceProvider LocalServiceProviderAsync { get { return _serviceProvider; } } + public ApiPortVSPackage() : base() { @@ -51,13 +56,13 @@ protected override void Dispose(bool disposing) } // Called after constructor when package is sited - protected override void Initialize() + protected async override System.Threading.Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress progress) { - base.Initialize(); + await base.InitializeAsync(cancellationToken, progress); - if (GetService(typeof(IMenuCommandService)) is OleMenuCommandService mcs) + if (await GetServiceAsync(typeof(IMenuCommandService)) is OleMenuCommandService mcs) { - var menuInitializer = LocalServiceProvider.GetService(typeof(AnalyzeMenu)) as AnalyzeMenu; + var menuInitializer = await LocalServiceProviderAsync.GetServiceAsync(typeof(AnalyzeMenu)) as AnalyzeMenu; // Add menu items for Analyze toolbar menu CommandID anazlyMenuCommandID = new CommandID(Guids.AnalyzeMenuItemCmdSet, (int)PkgCmdID.CmdIdAnalyzeMenuItem); diff --git a/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs b/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs index d02ae1ac8..22664e66e 100644 --- a/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs +++ b/src/ApiPort/ApiPort.VisualStudio/ServiceProvider.cs @@ -21,12 +21,13 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using static Microsoft.VisualStudio.VSConstants; namespace ApiPortVS { - internal sealed class ServiceProvider : IDisposable, IServiceProvider + internal sealed class ServiceProvider : IDisposable, IAsyncServiceProvider, IServiceProvider { private const string DefaultEndpoint = @"https://portability.dot.net/"; private static readonly DirectoryInfo AssemblyDirectory = new FileInfo(typeof(ServiceProvider).Assembly.Location).Directory; @@ -137,11 +138,6 @@ public ServiceProvider(ApiPortVSPackage serviceProvider) _container = builder.Build(); } - public object GetService(Type serviceType) - { - return _container.Resolve(serviceType); - } - public void Dispose() { _container.Dispose(); @@ -214,5 +210,15 @@ private static OutputViewModel GetOutputViewModel(IComponentContext context) return new OutputViewModel(validReports.Select(x => x.FullName)); } + + Task IAsyncServiceProvider.GetServiceAsync(Type serviceType) + { + return System.Threading.Tasks.Task.FromResult(_container.Resolve(serviceType)); + } + + public object GetService(Type serviceType) + { + return _container.Resolve(serviceType); + } } } diff --git a/src/ApiPort/ApiPort.Vsix/ApiPort.Vsix.csproj b/src/ApiPort/ApiPort.Vsix/ApiPort.Vsix.csproj index 21d0efc39..7c2a216a0 100644 --- a/src/ApiPort/ApiPort.Vsix/ApiPort.Vsix.csproj +++ b/src/ApiPort/ApiPort.Vsix/ApiPort.Vsix.csproj @@ -21,6 +21,11 @@ True false CS2008;$(NoWarn) + + + + + 15.0 true diff --git a/src/ApiPort/ApiPort.Vsix/source.extension.vsixmanifest b/src/ApiPort/ApiPort.Vsix/source.extension.vsixmanifest index f2318d59f..bb9e8ea75 100644 --- a/src/ApiPort/ApiPort.Vsix/source.extension.vsixmanifest +++ b/src/ApiPort/ApiPort.Vsix/source.extension.vsixmanifest @@ -11,11 +11,11 @@ code analysis, cross-platform, .NET Framework, .NET, portable, cross platform, Portable Library - - - - - + + + + + @@ -24,7 +24,7 @@ - - + + \ No newline at end of file From 721024e53e84b317c76ba2342d99a2e2f3b4a9e1 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 13 Nov 2018 15:14:23 -0800 Subject: [PATCH 16/17] Update guidance for DefineDynamicAssembly (#723) --- docs/RecommendedChanges/System/Remove usage.md | 1 - .../System/Use AssemblyBuilder.DefineDynamicAssembly.md | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 docs/RecommendedChanges/System/Use AssemblyBuilder.DefineDynamicAssembly.md diff --git a/docs/RecommendedChanges/System/Remove usage.md b/docs/RecommendedChanges/System/Remove usage.md index ef7e597af..83e8aa656 100644 --- a/docs/RecommendedChanges/System/Remove usage.md +++ b/docs/RecommendedChanges/System/Remove usage.md @@ -3,7 +3,6 @@ Remove usage. ### Affected APIs * `T:System.AccessViolationException` -* `T:System.AppDomain` * `T:System.AppDomainManager` * `T:System.AppDomainManagerInitializationOptions` * `T:System.AppDomainSetup` diff --git a/docs/RecommendedChanges/System/Use AssemblyBuilder.DefineDynamicAssembly.md b/docs/RecommendedChanges/System/Use AssemblyBuilder.DefineDynamicAssembly.md new file mode 100644 index 000000000..bc4b53566 --- /dev/null +++ b/docs/RecommendedChanges/System/Use AssemblyBuilder.DefineDynamicAssembly.md @@ -0,0 +1,5 @@ +### Recommended Action +Use AssemblyBuilder.DefineDynamicAssembly + +### Affected APIs +* `M:System.AppDomain.DefineDynamicAssembly` From 19f18f2e64d82e83ff0a42c252fb8341210c1ead Mon Sep 17 00:00:00 2001 From: Connie Yau Date: Wed, 14 Nov 2018 10:05:23 +0100 Subject: [PATCH 17/17] Updating member docIds (#724) --- .../Use AssemblyBuilder.DefineDynamicAssembly.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/RecommendedChanges/System/Use AssemblyBuilder.DefineDynamicAssembly.md b/docs/RecommendedChanges/System/Use AssemblyBuilder.DefineDynamicAssembly.md index bc4b53566..e60d2889e 100644 --- a/docs/RecommendedChanges/System/Use AssemblyBuilder.DefineDynamicAssembly.md +++ b/docs/RecommendedChanges/System/Use AssemblyBuilder.DefineDynamicAssembly.md @@ -2,4 +2,16 @@ Use AssemblyBuilder.DefineDynamicAssembly ### Affected APIs -* `M:System.AppDomain.DefineDynamicAssembly` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.Security.Policy.Evidence)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.Security.Policy.Evidence,System.Security.PermissionSet,System.Security.PermissionSet,System.Security.PermissionSet)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.Collections.Generic.IEnumerable{System.Reflection.Emit.CustomAttributeBuilder})` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.Collections.Generic.IEnumerable{System.Reflection.Emit.CustomAttributeBuilder},System.Security.SecurityContextSource)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.Security.PermissionSet,System.Security.PermissionSet,System.Security.PermissionSet)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.String)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.String,System.Boolean,System.Collections.Generic.IEnumerable{System.Reflection.Emit.CustomAttributeBuilder})` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.String,System.Security.Policy.Evidence)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.String,System.Security.Policy.Evidence,System.Security.PermissionSet,System.Security.PermissionSet,System.Security.PermissionSet)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.String,System.Security.Policy.Evidence,System.Security.PermissionSet,System.Security.PermissionSet,System.Security.PermissionSet,System.Boolean)` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.String,System.Security.Policy.Evidence,System.Security.PermissionSet,System.Security.PermissionSet,System.Security.PermissionSet,System.Boolean,System.Collections.Generic.IEnumerable{System.Reflection.Emit.CustomAttributeBuilder})` +* `M:System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName,System.Reflection.Emit.AssemblyBuilderAccess,System.String,System.Security.PermissionSet,System.Security.PermissionSet,System.Security.PermissionSet)`