| File: MSBuild\BuildHostProjectFileInfoProvider.cs | Web Access |
| Project: src\roslyn\src\Workspaces\MSBuild\Core\Microsoft.CodeAnalysis.Workspaces.MSBuild.csproj (Microsoft.CodeAnalysis.Workspaces.MSBuild) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Microsoft.CodeAnalysis.MSBuild; internal sealed class BuildHostProjectFileInfoProvider( BuildHostProcessManager buildHostProcessManager, ProjectFileExtensionRegistry projectFileExtensionRegistry, DiagnosticReporter diagnosticReporter, IProgress<ProjectLoadProgress>? progress) : IProjectFileInfoProvider { public async Task<ImmutableArray<ProjectFileInfo>> LoadProjectFileInfosAsync(string projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken) { if (!projectFileExtensionRegistry.TryGetLanguageNameFromProjectPath(projectPath, reportingOptions.OnLoaderFailure, out var languageName)) { return []; // Failure should already be reported. } var preferredBuildHostKind = BuildHostProcessManager.GetKindForProject(projectPath); var (buildHost, _) = await buildHostProcessManager.GetBuildHostWithFallbackAsync(preferredBuildHostKind, projectPath, cancellationToken).ConfigureAwait(false); var projectFile = await progress.DoOperationAndReportProgressAsync( ProjectLoadOperation.Evaluate, projectPath, targetFramework: null, () => buildHost.LoadProjectFileAsync(projectPath, languageName, cancellationToken) ).ConfigureAwait(false); // If there were any failures during load, we won't be able to build the project. So, bail early with an empty project. var diagnosticItems = await projectFile.GetDiagnosticLogItemsAsync(cancellationToken).ConfigureAwait(false); if (diagnosticItems.Any(d => d.Kind == DiagnosticLogItemKind.Error)) { diagnosticReporter.Report(diagnosticItems); return [ProjectFileInfo.CreateEmpty(languageName, projectPath)]; } var projectFileInfos = await progress.DoOperationAndReportProgressAsync( ProjectLoadOperation.Build, projectPath, targetFramework: null, () => projectFile.GetProjectFileInfosAsync(cancellationToken) ).ConfigureAwait(false); // We'll go check for any further diagnostics and report them diagnosticItems = await projectFile.GetDiagnosticLogItemsAsync(cancellationToken).ConfigureAwait(false); diagnosticReporter.Report(diagnosticItems); return projectFileInfos; } public async Task<ImmutableArray<string>> GetProjectOutputPathsAsync(string projectPath, CancellationToken cancellationToken) { // TODO: Should return multiple output paths for multi-targeted projects. // https://github.com/dotnet/roslyn/issues/81589 var buildHost = await buildHostProcessManager.GetBuildHostWithFallbackAsync(projectPath, cancellationToken).ConfigureAwait(false); var path = await buildHost.TryGetProjectOutputPathAsync(projectPath, cancellationToken).ConfigureAwait(false); return string.IsNullOrEmpty(path) ? [] : [path]; } }