Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use IBuildDependencyProjectReferencesService to read projects references for CPS based packages.config projects #4205

Merged
merged 6 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="PackageFeeds\PackageSourceMoniker.cs" />
<Compile Include="PackageFeeds\RecommenderPackageFeed.cs" />
<Compile Include="ProjectServices\CpsProjectSystemReferenceReader.cs" />
<Compile Include="Projects\PackageReferenceProject.cs" />
<Compile Include="Projects\ProjectPackages.cs" />
<Compile Include="Services\ISharedServiceState.cs" />
Expand All @@ -66,7 +67,7 @@
<Compile Include="Common\PackageCollectionItem.cs" />
<Compile Include="Common\PackageCollectionItemExtensions.cs" />
<Compile Include="PackageFeeds\LoadingStatusExtensionMethods.cs" />
<Compile Include="ProjectServices\NetCoreProjectSystemServices.cs" />
<Compile Include="ProjectServices\CpsProjectSystemServices.cs" />
<Compile Include="ProjectServices\VsCoreProjectSystemReferenceReader.cs" />
<Compile Include="ProjectSystems\VsCoreProjectSystem.cs" />
<Compile Include="Projects\VsMSBuildProjectSystemServices.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft;
using Microsoft.VisualStudio.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.Properties;
using Microsoft.VisualStudio.ProjectSystem.References;
using Microsoft.VisualStudio.Threading;
using NuGet.Frameworks;
using NuGet.LibraryModel;
using NuGet.ProjectManagement;
using NuGet.ProjectModel;
using NuGet.VisualStudio;

namespace NuGet.PackageManagement.VisualStudio
{
/// <summary>
/// Reference reader implementation for the core project system in the integrated development environment (IDE).
/// </summary>
internal class CpsProjectSystemReferenceReader
nkolev92 marked this conversation as resolved.
Show resolved Hide resolved
: IProjectSystemReferencesReader
{
private readonly IVsProjectAdapter _vsProjectAdapter;
private readonly IVsProjectThreadingService _threadingService;
private readonly AsyncLazy<UnconfiguredProject> _unconfiguredProject;

public CpsProjectSystemReferenceReader(
IVsProjectAdapter vsProjectAdapter,
IVsProjectThreadingService threadingService)
{
Assumes.Present(vsProjectAdapter);
Assumes.Present(threadingService);

_vsProjectAdapter = vsProjectAdapter;
_threadingService = threadingService;
_unconfiguredProject = new AsyncLazy<UnconfiguredProject>(async () =>
{
await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();

var context = _vsProjectAdapter.Project as IVsBrowseObjectContext;
nkolev92 marked this conversation as resolved.
Show resolved Hide resolved
if (context == null)
{
// VC implements this on their DTE.Project.Object
context = _vsProjectAdapter.Project.Object as IVsBrowseObjectContext;
}
return context?.UnconfiguredProject;
}, threadingService.JoinableTaskFactory);
}

public async Task<IEnumerable<ProjectRestoreReference>> GetProjectReferencesAsync(
Common.ILogger logger, CancellationToken _)
{
var unconfiguredProject = await _unconfiguredProject.GetValueAsync();
IBuildDependencyProjectReferencesService service = await GetProjectReferencesService(unconfiguredProject);

if (service == null)
{
return Enumerable.Empty<ProjectRestoreReference>();
}

var results = new List<ProjectRestoreReference>();
var hasMissingReferences = false;

foreach (IUnresolvedBuildDependencyProjectReference projectReference in await service.GetUnresolvedReferencesAsync())
{
try
{
if (await projectReference.GetReferenceOutputAssemblyAsync())
{
string childProjectPath = projectReference.EvaluatedIncludeAsFullPath;
var projectRestoreReference = new ProjectRestoreReference()
{
ProjectPath = childProjectPath,
ProjectUniqueName = childProjectPath
};

results.Add(projectRestoreReference);
}
}
catch (Exception ex)
{
hasMissingReferences = true;
logger.LogDebug(ex.ToString());
}
}

if (hasMissingReferences)
{
// Log a generic message once per project if any items could not be resolved.
// In most cases this can be ignored, but in the rare case where the unresolved
// item is actually a project the restore result will be incomplete.
var message = string.Format(
CultureInfo.CurrentCulture,
Strings.UnresolvedItemDuringProjectClosureWalk,
_vsProjectAdapter.UniqueName);

logger.LogVerbose(message);
}

return results;
}

/// <summary>
/// Gets the project reference service for the suggested configured project if available, <see langword="null"/> otherwise.
/// </summary>
private static async Task<IBuildDependencyProjectReferencesService> GetProjectReferencesService(UnconfiguredProject unconfiguredProject)
{
IBuildDependencyProjectReferencesService service = null;

if (unconfiguredProject != null)
{
ConfiguredProject configuredProject = await unconfiguredProject.GetSuggestedConfiguredProjectAsync();

if (configuredProject != null)
{
service = configuredProject.Services.ProjectReferences;
}
}

return service;
}

public Task<IEnumerable<LibraryDependency>> GetPackageReferencesAsync(
NuGetFramework targetFramework, CancellationToken _)
{
throw new NotSupportedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ namespace NuGet.PackageManagement.VisualStudio
/// <summary>
/// Represent net core project systems in visual studio.
/// </summary>
internal class NetCoreProjectSystemServices :
internal class CpsProjectSystemServices :
INuGetProjectServices
{
public NetCoreProjectSystemServices(
public CpsProjectSystemServices(
IVsProjectAdapter vsProjectAdapter,
Lazy<IScriptExecutor> scriptExecutor)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ await vsProject.IsCapabilityMatchAsync(NuGet.VisualStudio.IDE.ProjectCapabilitie
var fullProjectPath = vsProject.FullProjectPath;
var unconfiguredProject = GetUnconfiguredProject(vsProject.Project);

var projectServices = new NetCoreProjectSystemServices(vsProject, _scriptExecutor);
var projectServices = new CpsProjectSystemServices(vsProject, _scriptExecutor);

return new CpsPackageReferenceProject(
vsProject.ProjectName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ public VsMSBuildProjectSystemServices(
_vsProjectSystem = vsProjectSystem;
_threadingService = threadingService;

ReferencesReader = new VsCoreProjectSystemReferenceReader(vsProjectAdapter, threadingService);
ReferencesReader = vsProjectSystem is CpsProjectSystem ?
new CpsProjectSystemReferenceReader(vsProjectAdapter, _threadingService) :
new VsCoreProjectSystemReferenceReader(vsProjectAdapter, _threadingService);
ScriptService = new VsProjectScriptHostService(vsProjectAdapter, scriptExecutor);
}
}
Expand Down