diff --git a/.editorconfig b/.editorconfig index c95d5757826e7..6f544ccf0f5cd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -39,6 +39,7 @@ indent_size = 2 [*.{cs,vb}] # Sort using and Import directives with System.* appearing first dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = false # Avoid "this." and "Me." if not necessary dotnet_style_qualification_for_field = false:refactoring dotnet_style_qualification_for_property = false:refactoring diff --git a/eng/Versions.props b/eng/Versions.props index bf720fcdc0592..9da461804ff4a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -48,11 +48,11 @@ 0.9.2 2.2.0 5.0.2.5153 - 15.1.548 - 15.1.548 + 15.3.409 + 15.3.409 1.2.2 - 15.1.548 - 15.1.548 + 15.3.409 + 15.3.409 $(RoslynDiagnosticsNugetPackageVersion) 2.0.0-rc2-61102-09 $(MicrosoftCodeAnalysisTestingVersion) diff --git a/src/Tools/AnalyzerRunner/AnalyzerRunner.csproj b/src/Tools/AnalyzerRunner/AnalyzerRunner.csproj index f39beab0c1a60..192a4413983bb 100644 --- a/src/Tools/AnalyzerRunner/AnalyzerRunner.csproj +++ b/src/Tools/AnalyzerRunner/AnalyzerRunner.csproj @@ -16,7 +16,9 @@ + + diff --git a/src/Workspaces/Core/MSBuild/MSBuild/Build/ProjectBuildManager.cs b/src/Workspaces/Core/MSBuild/MSBuild/Build/ProjectBuildManager.cs index 76cb16ffb511b..fe4069d707c79 100644 --- a/src/Workspaces/Core/MSBuild/MSBuild/Build/ProjectBuildManager.cs +++ b/src/Workspaces/Core/MSBuild/MSBuild/Build/ProjectBuildManager.cs @@ -2,14 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +# nullable enable + using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Xml; +using Microsoft.Build.Framework; using Microsoft.CodeAnalysis.MSBuild.Logging; using Roslyn.Utilities; using MSB = Microsoft.Build; @@ -57,9 +61,9 @@ internal class ProjectBuildManager }.ToImmutableDictionary(); private readonly ImmutableDictionary _additionalGlobalProperties; - - private MSB.Evaluation.ProjectCollection _batchBuildProjectCollection; - private MSBuildDiagnosticLogger _batchBuildLogger; + private readonly ILogger? _msbuildLogger; + private MSB.Evaluation.ProjectCollection? _batchBuildProjectCollection; + private MSBuildDiagnosticLogger? _batchBuildLogger; private bool _batchBuildStarted; ~ProjectBuildManager() @@ -70,22 +74,23 @@ internal class ProjectBuildManager } } - public ProjectBuildManager(ImmutableDictionary additionalGlobalProperties) + public ProjectBuildManager(ImmutableDictionary additionalGlobalProperties, ILogger? msbuildLogger = null) { _additionalGlobalProperties = additionalGlobalProperties ?? ImmutableDictionary.Empty; + _msbuildLogger = msbuildLogger; } private ImmutableDictionary AllGlobalProperties => s_defaultGlobalProperties.AddRange(_additionalGlobalProperties); - private static async Task<(MSB.Evaluation.Project project, DiagnosticLog log)> LoadProjectAsync( - string path, MSB.Evaluation.ProjectCollection projectCollection, CancellationToken cancellationToken) + private static async Task<(MSB.Evaluation.Project? project, DiagnosticLog log)> LoadProjectAsync( + string path, MSB.Evaluation.ProjectCollection? projectCollection, CancellationToken cancellationToken) { var log = new DiagnosticLog(); try { - var loadedProjects = projectCollection.GetLoadedProjects(path); + var loadedProjects = projectCollection?.GetLoadedProjects(path); if (loadedProjects != null && loadedProjects.Count > 0) { Debug.Assert(loadedProjects.Count == 1); @@ -115,7 +120,7 @@ public ProjectBuildManager(ImmutableDictionary additionalGlobalP } } - public Task<(MSB.Evaluation.Project project, DiagnosticLog log)> LoadProjectAsync( + public Task<(MSB.Evaluation.Project? project, DiagnosticLog log)> LoadProjectAsync( string path, CancellationToken cancellationToken) { if (_batchBuildStarted) @@ -137,7 +142,7 @@ public ProjectBuildManager(ImmutableDictionary additionalGlobalP } } - public async Task TryGetOutputFilePathAsync( + public async Task TryGetOutputFilePathAsync( string path, CancellationToken cancellationToken) { Debug.Assert(_batchBuildStarted); @@ -150,7 +155,7 @@ public ProjectBuildManager(ImmutableDictionary additionalGlobalP public bool BatchBuildStarted => _batchBuildStarted; - public void StartBatchBuild(IDictionary globalProperties = null) + public void StartBatchBuild(IDictionary? globalProperties = null) { if (_batchBuildStarted) { @@ -160,7 +165,6 @@ public void StartBatchBuild(IDictionary globalProperties = null) globalProperties = globalProperties ?? ImmutableDictionary.Empty; var allProperties = s_defaultGlobalProperties.AddRange(globalProperties); _batchBuildProjectCollection = new MSB.Evaluation.ProjectCollection(allProperties); - _batchBuildLogger = new MSBuildDiagnosticLogger() { Verbosity = MSB.Framework.LoggerVerbosity.Normal @@ -168,7 +172,9 @@ public void StartBatchBuild(IDictionary globalProperties = null) var buildParameters = new MSB.Execution.BuildParameters(_batchBuildProjectCollection) { - Loggers = new MSB.Framework.ILogger[] { _batchBuildLogger } + Loggers = _msbuildLogger is null + ? (new MSB.Framework.ILogger[] { _batchBuildLogger }) + : (new MSB.Framework.ILogger[] { _batchBuildLogger, _msbuildLogger }) }; MSB.Execution.BuildManager.DefaultBuildManager.BeginBuild(buildParameters); @@ -186,7 +192,7 @@ public void EndBatchBuild() MSB.Execution.BuildManager.DefaultBuildManager.EndBuild(); // unload project so collection will release global strings - _batchBuildProjectCollection.UnloadAllProjects(); + _batchBuildProjectCollection?.UnloadAllProjects(); _batchBuildProjectCollection = null; _batchBuildLogger = null; _batchBuildStarted = false; @@ -219,7 +225,7 @@ public void EndBatchBuild() } } - _batchBuildLogger.SetProjectAndLog(projectInstance.FullPath, log); + _batchBuildLogger?.SetProjectAndLog(projectInstance.FullPath, log); var buildRequestData = new MSB.Execution.BuildRequestData(projectInstance, targets); diff --git a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs index f57c4f56af12d..7f1cd8a3fe43a 100644 --- a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs +++ b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs @@ -2,16 +2,20 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +# nullable enable + using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Build.Framework; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.MSBuild.Build; @@ -49,7 +53,7 @@ private partial class Worker /// /// Progress reporter. /// - private readonly IProgress _progress; + private readonly IProgress? _progress; /// /// Provides options for how failures should be reported when loading requested project files. @@ -66,7 +70,6 @@ private partial class Worker /// because it was requested. /// private readonly bool _preferMetadataForReferencesOfDiscoveredProjects; - private readonly Dictionary _projectIdToFileInfoMap; private readonly Dictionary> _projectIdToProjectReferencesMap; private readonly Dictionary> _pathToDiscoveredProjectInfosMap; @@ -80,8 +83,8 @@ private partial class Worker ImmutableArray requestedProjectPaths, string baseDirectory, ImmutableDictionary globalProperties, - ProjectMap projectMap, - IProgress progress, + ProjectMap? projectMap, + IProgress? progress, DiagnosticReportingOptions requestedProjectOptions, DiagnosticReportingOptions discoveredProjectOptions, bool preferMetadataForReferencesOfDiscoveredProjects) @@ -104,7 +107,7 @@ private partial class Worker _projectIdToProjectReferencesMap = new Dictionary>(); } - private async Task DoOperationAndReportProgressAsync(ProjectLoadOperation operation, string projectPath, string targetFramework, Func> doFunc) + private async Task DoOperationAndReportProgressAsync(ProjectLoadOperation operation, string projectPath, string? targetFramework, Func> doFunc) { var watch = _progress != null ? Stopwatch.StartNew() @@ -117,7 +120,7 @@ private async Task DoOperationAndReportProgressAsync(ProjectLo } finally { - if (_progress != null) + if (_progress != null && watch != null) { watch.Stop(); _progress.Report(new ProjectLoadProgress(projectPath, operation, targetFramework, watch.Elapsed)); @@ -297,9 +300,9 @@ private Task CreateProjectInfoAsync(ProjectFileInfo projectFileInfo var assemblyName = GetAssemblyNameFromProjectPath(projectPath); var parseOptions = GetLanguageService(language) - .GetDefaultParseOptions(); + ?.GetDefaultParseOptions(); var compilationOptions = GetLanguageService(language) - .GetDefaultCompilationOptions(); + ?.GetDefaultCompilationOptions(); return Task.FromResult( ProjectInfo.Create( @@ -329,6 +332,11 @@ private Task CreateProjectInfoAsync(ProjectFileInfo projectFileInfo // parse command line arguments var commandLineParser = GetLanguageService(projectFileInfo.Language); + if (commandLineParser is null) + { + throw new Exception($"Unable to find a '{nameof(ICommandLineParserService)}' for '{projectFileInfo.Language}'"); + } + var commandLineArgs = commandLineParser.Parse( arguments: projectFileInfo.CommandLineArgs, baseDirectory: projectDirectory, @@ -409,11 +417,16 @@ private static string GetAssemblyNameFromProjectPath(string projectFilePath) private IEnumerable ResolveAnalyzerReferences(CommandLineArguments commandLineArgs) { var analyzerService = GetWorkspaceService(); + if (analyzerService is null) + { + throw new Exception($"Unable to find '{nameof(IAnalyzerService)}'"); + } + var analyzerLoader = analyzerService.GetLoader(); foreach (var path in commandLineArgs.AnalyzerReferences.Select(r => r.FilePath)) { - string fullPath; + string? fullPath; if (PathUtilities.IsAbsolute(path)) { @@ -429,7 +442,7 @@ private IEnumerable ResolveAnalyzerReferences(CommandLineArgu return commandLineArgs.ResolveAnalyzerReferences(analyzerLoader); } - private static ImmutableArray CreateDocumentInfos(IReadOnlyList documentFileInfos, ProjectId projectId, Encoding encoding) + private static ImmutableArray CreateDocumentInfos(IReadOnlyList documentFileInfos, ProjectId projectId, Encoding? encoding) { var results = ImmutableArray.CreateBuilder(); @@ -482,6 +495,9 @@ private void CheckForDuplicateDocuments(ImmutableArray documents, var paths = new HashSet(PathUtilities.Comparer); foreach (var doc in documents) { + if (doc.FilePath is null) + continue; + if (paths.Contains(doc.FilePath)) { var message = string.Format(WorkspacesResources.Duplicate_source_file_0_in_project_1, doc.FilePath, projectFilePath); @@ -494,12 +510,14 @@ private void CheckForDuplicateDocuments(ImmutableArray documents, } } + [return: MaybeNull] private TLanguageService GetLanguageService(string languageName) where TLanguageService : ILanguageService => _workspaceServices .GetLanguageServices(languageName) .GetService(); + [return: MaybeNull] private TWorkspaceService GetWorkspaceService() where TWorkspaceService : IWorkspaceService => _workspaceServices diff --git a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker_ResolveReferences.cs b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker_ResolveReferences.cs index d5bfdc9adebab..5a432146f3beb 100644 --- a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker_ResolveReferences.cs +++ b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker_ResolveReferences.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +# nullable enable + using System.Collections.Generic; using System.Collections.Immutable; using System.IO; @@ -78,7 +80,7 @@ public ResolvedReferencesBuilder(IEnumerable metadataReferenc return builder.ToImmutable(); } - private static string GetFilePath(MetadataReference metadataReference) + private static string? GetFilePath(MetadataReference metadataReference) { switch (metadataReference) { @@ -96,11 +98,14 @@ public void AddProjectReference(ProjectReference projectReference) _projectReferences.Add(projectReference); } - public void SwapMetadataReferenceForProjectReference(ProjectReference projectReference, params string[] possibleMetadataReferencePaths) + public void SwapMetadataReferenceForProjectReference(ProjectReference projectReference, params string?[] possibleMetadataReferencePaths) { foreach (var path in possibleMetadataReferencePaths) { - Remove(path); + if (path != null) + { + Remove(path); + } } AddProjectReference(projectReference); @@ -124,12 +129,15 @@ public void Remove(string filePath) } } - public ProjectInfo SelectProjectInfoByOutput(IEnumerable projectInfos) + public ProjectInfo? SelectProjectInfoByOutput(IEnumerable projectInfos) { foreach (var projectInfo in projectInfos) { - if (Contains(projectInfo.OutputFilePath) || - Contains(projectInfo.OutputRefFilePath)) + var outputFilePath = projectInfo.OutputFilePath; + var outputRefFilePath = projectInfo.OutputRefFilePath; + if (outputFilePath != null && + outputRefFilePath != null && + (Contains(outputFilePath) || Contains(outputRefFilePath))) { return projectInfo; } @@ -256,18 +264,21 @@ private async Task TryLoadAndAddReferenceAsync(ProjectId id, string projec } // Find the project reference info whose output we have a metadata reference for. - ProjectInfo projectReferenceInfo = null; + ProjectInfo? projectReferenceInfo = null; foreach (var info in projectReferenceInfos) { - if (builder.Contains(info.OutputFilePath) || - builder.Contains(info.OutputRefFilePath)) + var outputFilePath = info.OutputFilePath; + var outputRefFilePath = info.OutputRefFilePath; + if (outputFilePath != null && + outputRefFilePath != null && + (builder.Contains(outputFilePath) || builder.Contains(outputRefFilePath))) { projectReferenceInfo = info; break; } } - if (projectReferenceInfo == null) + if (projectReferenceInfo is null) { // We didn't find the project reference info that matches any of our metadata references. // In this case, we'll go ahead and use the first project reference info that was found, @@ -295,14 +306,16 @@ private async Task TryLoadAndAddReferenceAsync(ProjectId id, string projec // reference is an UnresolvedMetadataReference, which will throw when we try to create a // Compilation with it. - if (!File.Exists(projectReferenceInfo.OutputRefFilePath)) + var outputRefFilePath = projectReferenceInfo.OutputRefFilePath; + if (outputRefFilePath != null && !File.Exists(outputRefFilePath)) { - builder.Remove(projectReferenceInfo.OutputRefFilePath); + builder.Remove(outputRefFilePath); } - if (!File.Exists(projectReferenceInfo.OutputFilePath)) + var outputFilePath = projectReferenceInfo.OutputFilePath; + if (outputFilePath != null && !File.Exists(outputFilePath)) { - builder.Remove(projectReferenceInfo.OutputFilePath); + builder.Remove(outputFilePath); } } @@ -317,7 +330,8 @@ private bool IsProjectLoadable(string projectPath) private async Task VerifyUnloadableProjectOutputExistsAsync(string projectPath, ResolvedReferencesBuilder builder, CancellationToken cancellationToken) { var outputFilePath = await _buildManager.TryGetOutputFilePathAsync(projectPath, cancellationToken).ConfigureAwait(false); - return builder.Contains(outputFilePath) + return outputFilePath != null + && builder.Contains(outputFilePath) && File.Exists(outputFilePath); } diff --git a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.cs b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.cs index 0c34697b5d9dd..3b4596be93add 100644 --- a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.cs +++ b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.cs @@ -2,11 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +# nullable enable + using System; using System.Collections.Immutable; using System.IO; using System.Threading; using System.Threading.Tasks; +using Microsoft.Build.Framework; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.MSBuild.Build; using Roslyn.Utilities; @@ -33,8 +36,8 @@ public partial class MSBuildProjectLoader internal MSBuildProjectLoader( HostWorkspaceServices workspaceServices, DiagnosticReporter diagnosticReporter, - ProjectFileLoaderRegistry projectFileLoaderRegistry, - ImmutableDictionary properties) + ProjectFileLoaderRegistry? projectFileLoaderRegistry, + ImmutableDictionary? properties) { _workspaceServices = workspaceServices; _diagnosticReporter = diagnosticReporter; @@ -55,7 +58,7 @@ public partial class MSBuildProjectLoader /// The workspace whose services this should use. /// An optional dictionary of additional MSBuild properties and values to use when loading projects. /// These are the same properties that are passed to msbuild via the /property:<n>=<v> command line argument. - public MSBuildProjectLoader(Workspace workspace, ImmutableDictionary properties = null) + public MSBuildProjectLoader(Workspace workspace, ImmutableDictionary? properties = null) : this(workspace.Services, new DiagnosticReporter(workspace), projectFileLoaderRegistry: null, properties) { } @@ -107,7 +110,7 @@ public void AssociateFileExtensionWithLanguage(string projectFileExtension, stri _projectFileLoaderRegistry.AssociateFileExtensionWithLanguage(projectFileExtension, language); } - private void SetSolutionProperties(string solutionFilePath) + private void SetSolutionProperties(string? solutionFilePath) { const string SolutionDirProperty = "SolutionDir"; @@ -139,10 +142,12 @@ private DiagnosticReportingMode GetReportingModeForUnrecognizedProjects() /// The path to the solution file to be loaded. This may be an absolute path or a path relative to the /// current working directory. /// An optional that will receive updates as the solution is loaded. + /// An optional that will log msbuild results. /// An optional to allow cancellation of this operation. public async Task LoadSolutionInfoAsync( string solutionFilePath, - IProgress progress = null, + IProgress? progress = null, + ILogger? msbuildLogger = null, CancellationToken cancellationToken = default) { if (solutionFilePath == null) @@ -153,7 +158,7 @@ private DiagnosticReportingMode GetReportingModeForUnrecognizedProjects() if (!_pathResolver.TryGetAbsoluteSolutionPath(solutionFilePath, baseDirectory: Directory.GetCurrentDirectory(), DiagnosticReportingMode.Throw, out var absoluteSolutionPath)) { // TryGetAbsoluteSolutionPath should throw before we get here. - return null; + return null!; } using (_dataGuard.DisposableWait(cancellationToken)) @@ -182,7 +187,7 @@ private DiagnosticReportingMode GetReportingModeForUnrecognizedProjects() } } - var buildManager = new ProjectBuildManager(_properties); + var buildManager = new ProjectBuildManager(_properties, msbuildLogger); var worker = new Worker( _workspaceServices, @@ -191,7 +196,8 @@ private DiagnosticReportingMode GetReportingModeForUnrecognizedProjects() _projectFileLoaderRegistry, buildManager, projectPaths.ToImmutable(), - baseDirectory: Path.GetDirectoryName(absoluteSolutionPath), + // TryGetAbsoluteSolutionPath should not return an invalid path + baseDirectory: Path.GetDirectoryName(absoluteSolutionPath)!, _properties, projectMap: null, progress, @@ -218,11 +224,13 @@ private DiagnosticReportingMode GetReportingModeForUnrecognizedProjects() /// An optional that will be used to resolve project references to existing projects. /// This is useful when populating a custom . /// An optional that will receive updates as the project is loaded. + /// An optional that will log msbuild results. /// An optional to allow cancellation of this operation. public async Task> LoadProjectInfoAsync( string projectFilePath, - ProjectMap projectMap = null, - IProgress progress = null, + ProjectMap? projectMap = null, + IProgress? progress = null, + ILogger? msbuildLogger = null, CancellationToken cancellationToken = default) { if (projectFilePath == null) @@ -238,7 +246,7 @@ private DiagnosticReportingMode GetReportingModeForUnrecognizedProjects() onPathFailure: reportingMode, onLoaderFailure: reportingMode); - var buildManager = new ProjectBuildManager(_properties); + var buildManager = new ProjectBuildManager(_properties, msbuildLogger); var worker = new Worker( _workspaceServices, diff --git a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildWorkspace.cs b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildWorkspace.cs index bfa4c7e3c042d..6b984827a3d73 100644 --- a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildWorkspace.cs +++ b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildWorkspace.cs @@ -11,6 +11,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Build.Framework; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host; @@ -169,9 +170,25 @@ private string GetAbsolutePath(string path, string baseDirectoryPath) /// current working directory. /// An optional that will receive updates as the solution is opened. /// An optional to allow cancellation of this operation. + // 3.6 BACKCOMPAT OVERLOAD -- DO NOT TOUCH + public Task OpenSolutionAsync( + string solutionFilePath, + IProgress progress, + CancellationToken cancellationToken) + => OpenSolutionAsync(solutionFilePath, progress, msbuildLogger: null, cancellationToken); + + /// + /// Open a solution file and all referenced projects. + /// + /// The path to the solution file to be opened. This may be an absolute path or a path relative to the + /// current working directory. + /// An optional that will receive updates as the solution is opened. + /// An optional that will log msbuild results. + /// An optional to allow cancellation of this operation. public async Task OpenSolutionAsync( string solutionFilePath, IProgress progress = null, + ILogger msbuildLogger = null, CancellationToken cancellationToken = default) { if (solutionFilePath == null) @@ -181,7 +198,7 @@ private string GetAbsolutePath(string path, string baseDirectoryPath) this.ClearSolution(); - var solutionInfo = await _loader.LoadSolutionInfoAsync(solutionFilePath, progress, cancellationToken).ConfigureAwait(false); + var solutionInfo = await _loader.LoadSolutionInfoAsync(solutionFilePath, progress, msbuildLogger, cancellationToken).ConfigureAwait(false); // construct workspace from loaded project infos this.OnSolutionAdded(solutionInfo); @@ -198,9 +215,25 @@ private string GetAbsolutePath(string path, string baseDirectoryPath) /// current working directory. /// An optional that will receive updates as the project is opened. /// An optional to allow cancellation of this operation. + // 3.6 BACKCOMPAT OVERLOAD -- DO NOT TOUCH + public Task OpenProjectAsync( + string projectFilePath, + IProgress progress, + CancellationToken cancellationToken) + => OpenProjectAsync(projectFilePath, progress, msbuildLogger: null, cancellationToken); + + /// + /// Open a project file and all referenced projects. + /// + /// The path to the project file to be opened. This may be an absolute path or a path relative to the + /// current working directory. + /// An optional that will receive updates as the project is opened. + /// An optional that will log msbuild results.. + /// An optional to allow cancellation of this operation. public async Task OpenProjectAsync( string projectFilePath, IProgress progress = null, + ILogger msbuildLogger = null, CancellationToken cancellationToken = default) { if (projectFilePath == null) @@ -209,7 +242,7 @@ private string GetAbsolutePath(string path, string baseDirectoryPath) } var projectMap = ProjectMap.Create(this.CurrentSolution); - var projects = await _loader.LoadProjectInfoAsync(projectFilePath, projectMap, progress, cancellationToken).ConfigureAwait(false); + var projects = await _loader.LoadProjectInfoAsync(projectFilePath, projectMap, progress, msbuildLogger, cancellationToken).ConfigureAwait(false); // add projects to solution foreach (var project in projects) diff --git a/src/Workspaces/Core/MSBuild/PublicAPI.Shipped.txt b/src/Workspaces/Core/MSBuild/PublicAPI.Shipped.txt index 4d2271cb90f4f..7483fd244ccc7 100644 --- a/src/Workspaces/Core/MSBuild/PublicAPI.Shipped.txt +++ b/src/Workspaces/Core/MSBuild/PublicAPI.Shipped.txt @@ -3,8 +3,6 @@ Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.AssociateFileExtensionWithLanguage(string projectFileExtension, string language) -> void Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadMetadataForReferencedProjects.get -> bool Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadMetadataForReferencedProjects.set -> void -Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(string projectFilePath, Microsoft.CodeAnalysis.MSBuild.ProjectMap projectMap = null, System.IProgress progress = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task> -Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadSolutionInfoAsync(string solutionFilePath, System.IProgress progress = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.MSBuildProjectLoader(Microsoft.CodeAnalysis.Workspace workspace, System.Collections.Immutable.ImmutableDictionary properties = null) -> void Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Properties.get -> System.Collections.Immutable.ImmutableDictionary Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.SkipUnrecognizedProjects.get -> bool @@ -15,8 +13,6 @@ Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.CloseSolution() -> void Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Diagnostics.get -> System.Collections.Immutable.ImmutableList Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.LoadMetadataForReferencedProjects.get -> bool Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.LoadMetadataForReferencedProjects.set -> void -Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(string projectFilePath, System.IProgress progress = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task -Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenSolutionAsync(string solutionFilePath, System.IProgress progress = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Properties.get -> System.Collections.Immutable.ImmutableDictionary Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.SkipUnrecognizedProjects.get -> bool Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.SkipUnrecognizedProjects.set -> void diff --git a/src/Workspaces/Core/MSBuild/PublicAPI.Unshipped.txt b/src/Workspaces/Core/MSBuild/PublicAPI.Unshipped.txt index 8b137891791fe..4d907de1beefc 100644 --- a/src/Workspaces/Core/MSBuild/PublicAPI.Unshipped.txt +++ b/src/Workspaces/Core/MSBuild/PublicAPI.Unshipped.txt @@ -1 +1,6 @@ - +Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(string projectFilePath, Microsoft.CodeAnalysis.MSBuild.ProjectMap projectMap = null, System.IProgress progress = null, Microsoft.Build.Framework.ILogger msbuildLogger = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task> +Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadSolutionInfoAsync(string solutionFilePath, System.IProgress progress = null, Microsoft.Build.Framework.ILogger msbuildLogger = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(string projectFilePath, System.IProgress progress = null, Microsoft.Build.Framework.ILogger msbuildLogger = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(string projectFilePath, System.IProgress progress, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenSolutionAsync(string solutionFilePath, System.IProgress progress, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenSolutionAsync(string solutionFilePath, System.IProgress progress = null, Microsoft.Build.Framework.ILogger msbuildLogger = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task diff --git a/src/Workspaces/MSBuildTest/Microsoft.CodeAnalysis.Workspaces.MSBuild.UnitTests.csproj b/src/Workspaces/MSBuildTest/Microsoft.CodeAnalysis.Workspaces.MSBuild.UnitTests.csproj index 3d62f7031774a..e0a51e564b7ff 100644 --- a/src/Workspaces/MSBuildTest/Microsoft.CodeAnalysis.Workspaces.MSBuild.UnitTests.csproj +++ b/src/Workspaces/MSBuildTest/Microsoft.CodeAnalysis.Workspaces.MSBuild.UnitTests.csproj @@ -27,6 +27,8 @@ + + diff --git a/src/Workspaces/MSBuildTest/NetCoreTests.cs b/src/Workspaces/MSBuildTest/NetCoreTests.cs index 57a7425d9e4e5..3c02f8007798d 100644 --- a/src/Workspaces/MSBuildTest/NetCoreTests.cs +++ b/src/Workspaces/MSBuildTest/NetCoreTests.cs @@ -274,7 +274,7 @@ public async Task TestOpenProject_NetCoreMultiTFM_ProjectReference() await AssertNetCoreMultiTFMProject(projectFilePath); } - [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))] + [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable), AlwaysSkip = "https://github.com/dotnet/roslyn/issues/42772")] [Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] [Trait(Traits.Feature, Traits.Features.NetCore)] public async Task TestOpenProject_NetCoreMultiTFM_ProjectReferenceWithReversedTFMs()