Asynchronize access to IVsHierarchy. (#3701)

* Asynchronize access to IVsHierarchy.

* Reverting changes to VsTemplateWizard.cs

* Reverting changes to VsFrameworkCompatibilityTests.cs

* Fixing build break.

* Fixing public API in InternalAPITestHook.

* ProjectType: Using HashSet instead of arrays.

* LegacyPackageReferenceRestoreUtilityTests: Avoid duplicate calls.

* Fix CpsPackageReferenceProjectProvider.cs after mismerge on rebase.

* Remove unused GetAllEnvDTEProjects method.

* Ensure OnEnvDTEProjectAdded/Renamed is executed in entirety before continuing.

* Fix whitespace.

Co-authored-by: Srdjan Jovcic <srdjanj@microsoft.com>
This commit is contained in:
Srdjan JovčićandSrdjan Jovcic authored and GitHub committed 2020-10-29 09:21:44 -07:00
1 parent 2eab204630
commit f51de2ce35
32 files changed
+434 -454

No files matched your search

@@ -793,7 +793,7 @@ namespace NuGet.PackageManagement.PowerShellCmdlets
{
var notFoundException =
new ItemNotFoundException(
String.Format(
string.Format(
CultureInfo.CurrentCulture,
Resources.Cmdlet_ProjectNotFound, projectName));
@@ -831,7 +831,7 @@ namespace NuGet.PackageManagement.PowerShellCmdlets
[SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Justification = "This exception is passed to PowerShell. We really don't care about the type of exception here.")]
protected void WriteError(string message)
{
if (!String.IsNullOrEmpty(message))
if (!string.IsNullOrEmpty(message))
{
WriteError(new Exception(message));
}
@@ -1043,7 +1043,7 @@ namespace NuGet.PackageManagement.PowerShellCmdlets
if (path != null)
{
string command = "& " + PathUtility.EscapePSPath(path) + " $__rootPath $__toolsPath $__package $__project";
LogCore(MessageLevel.Info, String.Format(CultureInfo.CurrentCulture, Resources.Cmdlet_ExecutingScript, path));
LogCore(MessageLevel.Info, string.Format(CultureInfo.CurrentCulture, Resources.Cmdlet_ExecutingScript, path));
InvokeCommand.InvokeScript(command, false, PipelineResultTypes.Error, null, null);
}
@@ -149,8 +149,8 @@ namespace NuGet.PackageManagement.VisualStudio
var packageReferencesToBeReinstalled = ProjectRetargetingUtility.GetPackageReferencesMarkedForReinstallation(nuGetProject);
if (packageReferencesToBeReinstalled.Count > 0)
{
Debug.Assert(ProjectRetargetingUtility.IsNuGetInUse(project));
var projectHierarchy = project.ToVsHierarchy();
Debug.Assert(await ProjectRetargetingUtility.IsNuGetInUseAsync(project));
var projectHierarchy = await project.ToVsHierarchyAsync();
ShowRetargetingErrorTask(packageReferencesToBeReinstalled.Select(p => p.PackageIdentity.Id), projectHierarchy, TaskErrorCategory.Warning, TaskPriority.Normal);
}
}
@@ -275,9 +275,9 @@ namespace NuGet.PackageManagement.VisualStudio
if (packagesToBeReinstalled.Count > 0)
{
// By asserting that NuGet is in use, we are also asserting that NuGet.VisualStudio.dll is already loaded
// Hence, it is okay to call project.ToVsHierarchy()
Debug.Assert(ProjectRetargetingUtility.IsNuGetInUse(project));
var projectHierarchy = project.ToVsHierarchy();
// Hence, it is okay to call project.ToVsHierarchyAsync()
Debug.Assert(await ProjectRetargetingUtility.IsNuGetInUseAsync(project));
var projectHierarchy = await project.ToVsHierarchyAsync();
ShowRetargetingErrorTask(packagesToBeReinstalled.Select(p => p.Id), projectHierarchy, TaskErrorCategory.Error, TaskPriority.High);
}
// NuGet/Home#4833 Baseline
@@ -366,9 +366,16 @@ namespace NuGet.PackageManagement.VisualStudio
// first check with DTE, and if we find any supported project, then return immediately.
var dte = await _asyncServiceProvider.GetDTEAsync();
var isSupported = EnvDTESolutionUtility.GetAllEnvDTEProjects(dte)
.Where(EnvDTEProjectUtility.IsSupported)
.Any();
var isSupported = false;
foreach (Project project in await EnvDTESolutionUtility.GetAllEnvDTEProjectsAsync(dte))
{
if (await EnvDTEProjectUtility.IsSupportedAsync(project))
{
isSupported = true;
break;
}
}
return isSupported;
}
@@ -540,15 +547,13 @@ namespace NuGet.PackageManagement.VisualStudio
private void OnEnvDTEProjectRenamed(Project envDTEProject, string oldName)
{
NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async () =>
NuGetUIThreadHelper.JoinableTaskFactory.Run(async () =>
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
if (!string.IsNullOrEmpty(oldName) && await IsSolutionOpenAsync() && _solutionOpenedRaised)
{
await EnsureNuGetAndVsProjectAdapterCacheAsync();
if (EnvDTEProjectUtility.IsSupported(envDTEProject))
if (await EnvDTEProjectUtility.IsSupportedAsync(envDTEProject))
{
RemoveVsProjectAdapterFromCache(oldName);
@@ -565,11 +570,11 @@ namespace NuGet.PackageManagement.VisualStudio
AfterNuGetProjectRenamed?.Invoke(this, new NuGetProjectEventArgs(nuGetProject));
}
else if (EnvDTEProjectUtility.IsSolutionFolder(envDTEProject))
else if (await EnvDTEProjectUtility.IsSolutionFolderAsync(envDTEProject))
{
// In the case where a solution directory was changed, project FullNames are unchanged.
// We only need to invalidate the projects under the current tree so as to sync the CustomUniqueNames.
foreach (var item in EnvDTEProjectUtility.GetSupportedChildProjects(envDTEProject))
foreach (var item in await EnvDTEProjectUtility.GetSupportedChildProjectsAsync(envDTEProject))
{
RemoveVsProjectAdapterFromCache(item.FullName);
@@ -596,12 +601,10 @@ namespace NuGet.PackageManagement.VisualStudio
private void OnEnvDTEProjectAdded(Project envDTEProject)
{
NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async () =>
NuGetUIThreadHelper.JoinableTaskFactory.Run(async () =>
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
if (await IsSolutionOpenAsync()
&& EnvDTEProjectUtility.IsSupported(envDTEProject)
&& await EnvDTEProjectUtility.IsSupportedAsync(envDTEProject)
&& !EnvDTEProjectUtility.IsParentProjectExplicitlyUnsupported(envDTEProject)
&& _solutionOpenedRaised)
{
@@ -659,9 +662,14 @@ namespace NuGet.PackageManagement.VisualStudio
{
var dte = await _asyncServiceProvider.GetDTEAsync();
var supportedProjects = EnvDTESolutionUtility
.GetAllEnvDTEProjects(dte)
.Where(EnvDTEProjectUtility.IsSupported);
var supportedProjects = new List<Project>();
foreach (Project project in await EnvDTESolutionUtility.GetAllEnvDTEProjectsAsync(dte))
{
if (await EnvDTEProjectUtility.IsSupportedAsync(project))
{
supportedProjects.Add(project);
}
}
foreach (var project in supportedProjects)
{
@@ -697,7 +705,7 @@ namespace NuGet.PackageManagement.VisualStudio
private async Task AddVsProjectAdapterToCacheAsync(IVsProjectAdapter vsProjectAdapter)
{
if (!vsProjectAdapter.IsSupported)
if (!await vsProjectAdapter.IsSupportedAsync())
{
return;
}
@@ -74,7 +74,7 @@ namespace NuGet.PackageManagement.VisualStudio
continue;
}
if (EnvDTEProjectUtility.HasUnsupportedProjectCapability(reference3.SourceProject))
if (await EnvDTEProjectUtility.HasUnsupportedProjectCapabilityAsync(reference3.SourceProject))
{
// Skip this shared project
continue;
@@ -31,7 +31,7 @@ namespace NuGet.PackageManagement.VisualStudio
, IProjectSystemReferencesReader
, IProjectSystemReferencesService
{
private static readonly Array _referenceMetadata;
private static readonly Array ReferenceMetadata;
private readonly IVsProjectAdapter _vsProjectAdapter;
private readonly IVsProjectThreadingService _threadingService;
@@ -59,13 +59,13 @@ namespace NuGet.PackageManagement.VisualStudio
static VsManagedLanguagesProjectSystemServices()
{
_referenceMetadata = Array.CreateInstance(typeof(string), 6);
_referenceMetadata.SetValue(ProjectItemProperties.IncludeAssets, 0);
_referenceMetadata.SetValue(ProjectItemProperties.ExcludeAssets, 1);
_referenceMetadata.SetValue(ProjectItemProperties.PrivateAssets, 2);
_referenceMetadata.SetValue(ProjectItemProperties.NoWarn, 3);
_referenceMetadata.SetValue(ProjectItemProperties.GeneratePathProperty, 4);
_referenceMetadata.SetValue(ProjectItemProperties.Aliases, 5);
ReferenceMetadata = Array.CreateInstance(typeof(string), 6);
ReferenceMetadata.SetValue(ProjectItemProperties.IncludeAssets, 0);
ReferenceMetadata.SetValue(ProjectItemProperties.ExcludeAssets, 1);
ReferenceMetadata.SetValue(ProjectItemProperties.PrivateAssets, 2);
ReferenceMetadata.SetValue(ProjectItemProperties.NoWarn, 3);
ReferenceMetadata.SetValue(ProjectItemProperties.GeneratePathProperty, 4);
ReferenceMetadata.SetValue(ProjectItemProperties.Aliases, 5);
}
public VsManagedLanguagesProjectSystemServices(
@@ -108,7 +108,7 @@ namespace NuGet.PackageManagement.VisualStudio
{
if (AsVSProject4.PackageReferences.TryGetReference(
installedPackage,
_referenceMetadata,
ReferenceMetadata,
out var version,
out var metadataElements,
out var metadataValues))
@@ -139,23 +139,23 @@ namespace NuGet.PackageManagement.VisualStudio
return new ProjectRestoreReference[] { };
}
var references = AsVSProject4.References
.Cast<Reference6>()
.Where(r => r.SourceProject != null && EnvDTEProjectUtility.IsSupported(r.SourceProject))
.Select(reference =>
var references = new List<ProjectRestoreReference>();
foreach (Reference6 r in AsVSProject4.References.Cast<Reference6>())
{
if (r.SourceProject != null && await EnvDTEProjectUtility.IsSupportedAsync(r.SourceProject))
{
Array metadataElements;
Array metadataValues;
reference.GetMetadata(_referenceMetadata, out metadataElements, out metadataValues);
r.GetMetadata(ReferenceMetadata, out metadataElements, out metadataValues);
return new ProjectReference(
uniqueName: reference.SourceProject.FullName,
references.Add(ToProjectRestoreReference(new ProjectReference(
uniqueName: r.SourceProject.FullName,
metadataElements: metadataElements,
metadataValues: metadataValues);
})
.Select(ToProjectRestoreReference);
metadataValues: metadataValues)));
}
}
return references.ToList();
return references;
}
private static ProjectRestoreReference ToProjectRestoreReference(ProjectReference item)
@@ -31,13 +31,11 @@ namespace NuGet.PackageManagement.VisualStudio
}
NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var root = VsProjectAdapter.ProjectDirectory;
var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(root), targetFullPath);
await AddImportStatementAsync(location, relativeTargetPath);
});
{
var root = await VsProjectAdapter.GetProjectDirectoryAsync();
var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(root), targetFullPath);
await AddImportStatementAsync(location, relativeTargetPath);
});
}
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -62,14 +60,12 @@ namespace NuGet.PackageManagement.VisualStudio
}
NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var root = VsProjectAdapter.ProjectDirectory;
// For VS 2012 or above, the operation has to be done inside the Writer lock
var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(root), targetFullPath);
await RemoveImportStatementAsync(relativeTargetPath);
});
{
var root = await VsProjectAdapter.GetProjectDirectoryAsync();
// For VS 2012 or above, the operation has to be done inside the Writer lock
var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(root), targetFullPath);
await RemoveImportStatementAsync(relativeTargetPath);
});
}
// IMPORTANT: The NoInlining is required to prevent CLR from loading VisualStudio12.dll assembly while running
@@ -72,8 +72,7 @@ namespace NuGet.PackageManagement.VisualStudio
{
NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
_projectFullPath = VsProjectAdapter.ProjectDirectory;
_projectFullPath = await VsProjectAdapter.GetProjectDirectoryAsync();
});
}
@@ -465,7 +464,7 @@ namespace NuGet.PackageManagement.VisualStudio
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var containsFile = await EnvDTEProjectUtility.ContainsFile(VsProjectAdapter.Project, path);
var containsFile = await EnvDTEProjectUtility.ContainsFileAsync(VsProjectAdapter.Project, path);
return containsFile;
});
}
@@ -207,7 +207,7 @@ namespace NuGet.PackageManagement.VisualStudio
foreach (var projectReference in frameworkInfo.ProjectReferences)
{
if (SupportedProjectTypes.IsSupportedProjectExtension(projectReference.ProjectPath))
if (ProjectType.IsSupportedProjectExtension(projectReference.ProjectPath))
{
projectReferences.Add(projectReference);
}
@@ -82,8 +82,7 @@ namespace NuGet.PackageManagement.VisualStudio
public override async Task<string> GetCacheFilePathAsync()
{
await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();
return NoOpRestoreUtilities.GetProjectCacheFilePath(cacheRoot: GetMSBuildProjectExtensionsPath());
return NoOpRestoreUtilities.GetProjectCacheFilePath(cacheRoot: await GetMSBuildProjectExtensionsPathAsync());
}
public override async Task<string> GetAssetsFilePathOrNullAsync()
@@ -93,10 +92,7 @@ namespace NuGet.PackageManagement.VisualStudio
private async Task<string> GetAssetsFilePathAsync(bool shouldThrow)
{
await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();
var msbuildProjectExtensionsPath = GetMSBuildProjectExtensionsPath(shouldThrow);
var msbuildProjectExtensionsPath = await GetMSBuildProjectExtensionsPathAsync(shouldThrow);
if (msbuildProjectExtensionsPath == null)
{
return null;
@@ -204,9 +200,9 @@ namespace NuGet.PackageManagement.VisualStudio
{
await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();
EnvDTEProjectUtility.EnsureCheckedOutIfExists(_vsProjectAdapter.Project, _vsProjectAdapter.ProjectDirectory, filePath);
EnvDTEProjectUtility.EnsureCheckedOutIfExists(_vsProjectAdapter.Project, await _vsProjectAdapter.GetProjectDirectoryAsync(), filePath);
var isFileExistsInProject = await EnvDTEProjectUtility.ContainsFile(_vsProjectAdapter.Project, filePath);
var isFileExistsInProject = await EnvDTEProjectUtility.ContainsFileAsync(_vsProjectAdapter.Project, filePath);
if (!isFileExistsInProject)
{
@@ -221,18 +217,19 @@ namespace NuGet.PackageManagement.VisualStudio
var folderPath = Path.GetDirectoryName(filePath);
var fullPath = filePath;
if (filePath.Contains(_vsProjectAdapter.ProjectDirectory))
string projectDirectory = await _vsProjectAdapter.GetProjectDirectoryAsync();
if (filePath.Contains(projectDirectory))
{
// folderPath should always be relative to ProjectDirectory so if filePath already contains
// ProjectDirectory then get a relative path and construct folderPath to get the appropriate
// ProjectItems from dte where you have to add this file.
var relativeLockFilePath = FileSystemUtility.GetRelativePath(_vsProjectAdapter.ProjectDirectory, filePath);
var relativeLockFilePath = FileSystemUtility.GetRelativePath(projectDirectory, filePath);
folderPath = Path.GetDirectoryName(relativeLockFilePath);
}
else
{
// get the fullPath wrt ProjectDirectory
fullPath = FileSystemUtility.GetFullPath(_vsProjectAdapter.ProjectDirectory, filePath);
fullPath = FileSystemUtility.GetFullPath(projectDirectory, filePath);
}
var container = await EnvDTEProjectUtility.GetProjectItemsAsync(_vsProjectAdapter.Project, folderPath, createIfNotExists: true);
@@ -250,11 +247,11 @@ namespace NuGet.PackageManagement.VisualStudio
#endregion
private string GetMSBuildProjectExtensionsPath(bool shouldThrow = true)
private async Task<string> GetMSBuildProjectExtensionsPathAsync(bool shouldThrow = true)
{
ThreadHelper.ThrowIfNotOnUIThread();
await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();
var msbuildProjectExtensionsPath = _vsProjectAdapter.MSBuildProjectExtensionsPath;
var msbuildProjectExtensionsPath = await _vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync();
if (string.IsNullOrEmpty(msbuildProjectExtensionsPath))
{
@@ -263,7 +260,7 @@ namespace NuGet.PackageManagement.VisualStudio
throw new InvalidDataException(string.Format(
Strings.MSBuildPropertyNotFound,
ProjectBuildProperties.MSBuildProjectExtensionsPath,
_vsProjectAdapter.ProjectDirectory));
await _vsProjectAdapter.GetProjectDirectoryAsync()));
}
return null;
@@ -437,7 +434,7 @@ namespace NuGet.PackageManagement.VisualStudio
RestoreMetadata = new ProjectRestoreMetadata
{
ProjectStyle = ProjectStyle.PackageReference,
OutputPath = GetMSBuildProjectExtensionsPath(),
OutputPath = await GetMSBuildProjectExtensionsPathAsync(),
ProjectPath = _projectFullPath,
ProjectName = projectName,
ProjectUniqueName = _projectFullPath,
@@ -69,7 +69,7 @@ namespace NuGet.PackageManagement.VisualStudio
var folderNuGetProjectFullPath = context.PackagesPathFactory();
// Project folder path is the packages config folder path
var packagesConfigFolderPath = vsProjectAdapter.ProjectDirectory;
var packagesConfigFolderPath = await vsProjectAdapter.GetProjectDirectoryAsync();
return new VsMSBuildNuGetProject(
vsProjectAdapter,
@@ -35,19 +35,16 @@ namespace NuGet.PackageManagement.VisualStudio
#region Properties
public string MSBuildProjectExtensionsPath
public async Task<string> GetMSBuildProjectExtensionsPathAsync()
{
get
var msbuildProjectExtensionsPath = BuildProperties.GetPropertyValue(ProjectBuildProperties.MSBuildProjectExtensionsPath);
if (string.IsNullOrEmpty(msbuildProjectExtensionsPath))
{
var msbuildProjectExtensionsPath = BuildProperties.GetPropertyValue(ProjectBuildProperties.MSBuildProjectExtensionsPath);
if (string.IsNullOrEmpty(msbuildProjectExtensionsPath))
{
return null;
}
return Path.Combine(ProjectDirectory, msbuildProjectExtensionsPath);
return null;
}
return Path.Combine(await GetProjectDirectoryAsync(), msbuildProjectExtensionsPath);
}
public string RestorePackagesPath
@@ -101,18 +98,15 @@ namespace NuGet.PackageManagement.VisualStudio
public string FullName => ProjectNames.FullName;
public string ProjectDirectory
public async Task<string> GetProjectDirectoryAsync()
{
get
if (!IsDeferred)
{
if (!IsDeferred)
{
return Project.GetFullPath();
}
else
{
return Path.GetDirectoryName(FullProjectPath);
}
return await Project.GetFullPathAsync();
}
else
{
return Path.GetDirectoryName(FullProjectPath);
}
}
@@ -126,17 +120,14 @@ namespace NuGet.PackageManagement.VisualStudio
}
}
public bool IsSupported
public async Task<bool> IsSupportedAsync()
{
get
if (!IsDeferred)
{
if (!IsDeferred)
{
return EnvDTEProjectUtility.IsSupported(Project);
}
return VsHierarchyUtility.IsSupported(VsHierarchy, _projectTypeGuid);
return await EnvDTEProjectUtility.IsSupportedAsync(Project);
}
return await VsHierarchyUtility.IsSupportedAsync(VsHierarchy, _projectTypeGuid);
}
public string PackageTargetFallback
@@ -246,7 +237,7 @@ namespace NuGet.PackageManagement.VisualStudio
{
if (!IsDeferred)
{
return Project.GetProjectTypeGuids();
return await Project.GetProjectTypeGuidsAsync();
}
else
{
@@ -284,7 +275,7 @@ namespace NuGet.PackageManagement.VisualStudio
if (!IsDeferred)
{
if (Project.Kind != null
&& SupportedProjectTypes.IsSupportedForAddingReferences(Project.Kind))
&& ProjectType.IsSupportedForAddingReferences(Project.Kind))
{
return EnvDTEProjectUtility.GetReferencedProjects(Project).Select(p => p.UniqueName);
}
@@ -294,7 +285,7 @@ namespace NuGet.PackageManagement.VisualStudio
else
{
var projectTypeGuids = await GetProjectTypeGuidsAsync();
if (projectTypeGuids.All(SupportedProjectTypes.IsSupportedForAddingReferences))
if (projectTypeGuids.All(ProjectType.IsSupportedForAddingReferences))
{
return await _workspaceService.GetProjectReferencesAsync(FullProjectPath);
}
@@ -68,7 +68,7 @@ namespace NuGet.PackageManagement.VisualStudio
// switch to main thread and use services we know must be done on main thread.
await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();
var vsHierarchyItem = VsHierarchyItem.FromDteProject(dteProject);
var vsHierarchyItem = await VsHierarchyItem.FromDteProjectAsync(dteProject);
Func<IVsHierarchy, EnvDTE.Project> loadDteProject = _ => dteProject;
var buildStorageProperty = vsHierarchyItem.VsHierarchy as IVsBuildPropertyStorage;
@@ -45,17 +45,14 @@ namespace NuGet.PackageManagement.VisualStudio
#region Get Project Information
internal static bool IsSolutionFolder(EnvDTE.Project envDTEProject)
internal static async Task<bool> IsSolutionFolderAsync(EnvDTE.Project envDTEProject)
{
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
return envDTEProject.Kind != null && envDTEProject.Kind.Equals(VsProjectTypes.VsProjectItemKindSolutionFolder, StringComparison.OrdinalIgnoreCase);
}
public static async Task<bool> ContainsFile(EnvDTE.Project envDTEProject, string path)
public static async Task<bool> ContainsFileAsync(EnvDTE.Project envDTEProject, string path)
{
ThreadHelper.ThrowIfNotOnUIThread();
if (string.Equals(envDTEProject.Kind, VsProjectTypes.WixProjectTypeGuid, StringComparison.OrdinalIgnoreCase)
||
string.Equals(envDTEProject.Kind, VsProjectTypes.NemerleProjectTypeGuid, StringComparison.OrdinalIgnoreCase)
@@ -73,7 +70,10 @@ namespace NuGet.PackageManagement.VisualStudio
var item = await GetProjectItemAsync(envDTEProject, path);
return item != null;
}
var vsProject = (IVsProject)envDTEProject.ToVsHierarchy();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var vsProject = (IVsProject)(await envDTEProject.ToVsHierarchyAsync());
if (vsProject == null)
{
return false;
@@ -82,7 +82,7 @@ namespace NuGet.PackageManagement.VisualStudio
int pFound;
uint itemId;
if (IsProjectCapabilityCompliant(envDTEProject))
if (await IsProjectCapabilityCompliantAsync(envDTEProject))
{
// REVIEW: We want to revisit this after RTM - the code in this if statement should be applied to every project type.
// We're checking for VSDOCUMENTPRIORITY.DP_Standard here to see if the file is included in the project.
@@ -99,7 +99,7 @@ namespace NuGet.PackageManagement.VisualStudio
// Get the ProjectItems for a folder path
public static async Task<EnvDTE.ProjectItems> GetProjectItemsAsync(EnvDTE.Project envDTEProject, string folderPath, bool createIfNotExists)
{
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
if (string.IsNullOrEmpty(folderPath))
{
@@ -113,7 +113,7 @@ namespace NuGet.PackageManagement.VisualStudio
// Both types have the ProjectItems property that we want to access.
object cursor = envDTEProject;
var fullPath = envDTEProject.GetFullPath();
var fullPath = await envDTEProject.GetFullPathAsync();
var folderRelativePath = string.Empty;
foreach (var part in pathParts)
@@ -204,7 +204,7 @@ namespace NuGet.PackageManagement.VisualStudio
// Execute command to include the existing folder into project. Must do this on UI thread.
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var projectHierarchy = (IVsUIHierarchy)envDTEProject.ToVsHierarchy();
var projectHierarchy = (IVsUIHierarchy)(await envDTEProject.ToVsHierarchyAsync());
uint itemId;
var hr = projectHierarchy.ParseCanonicalName(folderRelativePath, out itemId);
@@ -373,48 +373,45 @@ namespace NuGet.PackageManagement.VisualStudio
return references;
}
public static bool IsSupported(EnvDTE.Project envDTEProject)
public static async Task<bool> IsSupportedAsync(EnvDTE.Project envDTEProject)
{
Assumes.Present(envDTEProject);
ThreadHelper.ThrowIfNotOnUIThread();
if (SupportsProjectKPackageManager(envDTEProject))
{
return true;
}
if (IsProjectCapabilityCompliant(envDTEProject))
if (await IsProjectCapabilityCompliantAsync(envDTEProject))
{
return true;
}
return envDTEProject.Kind != null && SupportedProjectTypes.IsSupported(envDTEProject.Kind) && !HasUnsupportedProjectCapability(envDTEProject);
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
return envDTEProject.Kind != null && ProjectType.IsSupported(envDTEProject.Kind) && !await HasUnsupportedProjectCapabilityAsync(envDTEProject);
}
private static bool IsProjectCapabilityCompliant(EnvDTE.Project envDTEProject)
private static async Task<bool> IsProjectCapabilityCompliantAsync(EnvDTE.Project envDTEProject)
{
ThreadHelper.ThrowIfNotOnUIThread();
Debug.Assert(envDTEProject != null);
var hierarchy = envDTEProject.ToVsHierarchy();
return VsHierarchyUtility.IsProjectCapabilityCompliant(hierarchy);
var hierarchy = await envDTEProject.ToVsHierarchyAsync();
return await VsHierarchyUtility.IsProjectCapabilityCompliantAsync(hierarchy);
}
public async static Task<NuGetProject> GetNuGetProjectAsync(EnvDTE.Project project, ISolutionManager solutionManager)
{
ThreadHelper.ThrowIfNotOnUIThread();
Debug.Assert(project != null);
Debug.Assert(solutionManager != null);
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var nuGetProject = await solutionManager.GetNuGetProjectAsync(project.Name);
if (nuGetProject == null)
{
nuGetProject = await solutionManager.GetNuGetProjectAsync(project.UniqueName);
}
return nuGetProject;
}
@@ -432,15 +429,14 @@ namespace NuGet.PackageManagement.VisualStudio
/// Recursively retrieves all supported child projects of a virtual folder.
/// </summary>
/// <param name="project">The root container project</param>
internal static IEnumerable<EnvDTE.Project> GetSupportedChildProjects(EnvDTE.Project envDTEProject)
internal static async Task<IEnumerable<EnvDTE.Project>> GetSupportedChildProjectsAsync(EnvDTE.Project envDTEProject)
{
ThreadHelper.ThrowIfNotOnUIThread();
if (!IsSolutionFolder(envDTEProject))
if (!await IsSolutionFolderAsync(envDTEProject))
{
yield break;
return Array.Empty<EnvDTE.Project>();
}
var supportedChildProjects = new List<EnvDTE.Project>();
var containerProjects = new Queue<EnvDTE.Project>();
containerProjects.Enqueue(envDTEProject);
@@ -453,21 +449,23 @@ namespace NuGet.PackageManagement.VisualStudio
if (nestedProject == null)
{
}
else if (IsSupported(nestedProject))
else if (await IsSupportedAsync(nestedProject))
{
yield return nestedProject;
supportedChildProjects.Add(nestedProject);
}
else if (IsSolutionFolder(nestedProject))
else if (await IsSolutionFolderAsync(nestedProject))
{
containerProjects.Enqueue(nestedProject);
}
}
}
return supportedChildProjects;
}
internal static HashSet<string> GetAssemblyClosure(EnvDTE.Project envDTEProject, IDictionary<string, HashSet<string>> visitedProjects)
internal static async Task<HashSet<string>> GetAssemblyClosureAsync(EnvDTE.Project envDTEProject, IDictionary<string, HashSet<string>> visitedProjects)
{
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
HashSet<string> assemblies;
if (visitedProjects.TryGetValue(envDTEProject.UniqueName, out assemblies))
@@ -478,24 +476,24 @@ namespace NuGet.PackageManagement.VisualStudio
assemblies = new HashSet<string>(PathComparer.Default);
visitedProjects.Add(envDTEProject.UniqueName, assemblies);
var localProjectAssemblies = GetLocalProjectAssemblies(envDTEProject);
var localProjectAssemblies = await GetLocalProjectAssembliesAsync(envDTEProject);
CollectionsUtility.AddRange(assemblies, localProjectAssemblies);
var referencedProjects = GetReferencedProjects(envDTEProject);
foreach (var project in referencedProjects)
{
var assemblyClosure = GetAssemblyClosure(project, visitedProjects);
var assemblyClosure = await GetAssemblyClosureAsync(project, visitedProjects);
CollectionsUtility.AddRange(assemblies, assemblyClosure);
}
return assemblies;
}
private static HashSet<string> GetLocalProjectAssemblies(EnvDTE.Project envDTEProject)
private static async Task<HashSet<string>> GetLocalProjectAssembliesAsync(EnvDTE.Project envDTEProject)
{
if (envDTEProject.IsWebSite())
{
var websiteLocalAssemblies = GetWebsiteLocalAssemblies(envDTEProject);
var websiteLocalAssemblies = await GetWebsiteLocalAssembliesAsync(envDTEProject);
return websiteLocalAssemblies;
}
@@ -531,7 +529,7 @@ namespace NuGet.PackageManagement.VisualStudio
return assemblies;
}
private static HashSet<string> GetWebsiteLocalAssemblies(EnvDTE.Project envDTEProject)
private static async Task<HashSet<string>> GetWebsiteLocalAssembliesAsync(EnvDTE.Project envDTEProject)
{
var assemblies = new HashSet<string>(PathComparer.Default);
var references = GetAssemblyReferences(envDTEProject);
@@ -550,7 +548,7 @@ namespace NuGet.PackageManagement.VisualStudio
// For website projects, we always add .refresh files that point to the corresponding binaries in packages. In the event of bin deployed assemblies that are also GACed,
// the ReferenceKind is not AssemblyReferenceBin. Consequently, we work around this by looking for any additional assembly declarations specified via .refresh files.
var envDTEProjectPath = envDTEProject.GetFullPath();
var envDTEProjectPath = await envDTEProject.GetFullPathAsync();
CollectionsUtility.AddRange(assemblies, RefreshFileUtility.ResolveRefreshPaths(envDTEProjectPath));
return assemblies;
@@ -636,7 +634,7 @@ namespace NuGet.PackageManagement.VisualStudio
{
ThreadHelper.ThrowIfNotOnUIThread();
return envDTEProject.Kind == null || SupportedProjectTypes.IsUnsupported(envDTEProject.Kind);
return envDTEProject.Kind == null || ProjectType.IsUnsupported(envDTEProject.Kind);
}
public static bool IsParentProjectExplicitlyUnsupported(EnvDTE.Project envDTEProject)
@@ -710,9 +708,9 @@ namespace NuGet.PackageManagement.VisualStudio
{
var projectNameConfig = ProjectJsonPathUtilities.GetProjectConfigWithProjectName(project.Name);
var containsProjectJson = await ContainsFile(project, projectNameConfig);
var containsProjectJson = await ContainsFileAsync(project, projectNameConfig);
var containsProjectNameJson = await ContainsFile(
var containsProjectNameJson = await ContainsFileAsync(
project,
ProjectJsonPathUtilities.ProjectConfigFileName);
@@ -722,10 +720,9 @@ namespace NuGet.PackageManagement.VisualStudio
/// <summary>
/// Check if the project has an unsupported project capability, such as, "SharedAssetsProject"
/// </summary>
public static bool HasUnsupportedProjectCapability(EnvDTE.Project envDTEProject)
public static async Task<bool> HasUnsupportedProjectCapabilityAsync(EnvDTE.Project envDTEProject)
{
var hier = envDTEProject.ToVsHierarchy();
var hier = await envDTEProject.ToVsHierarchyAsync();
return VsHierarchyUtility.HasUnsupportedProjectCapability(hier);
}
@@ -6,25 +6,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NuGet.VisualStudio;
using Task = System.Threading.Tasks.Task;
namespace NuGet.PackageManagement.VisualStudio
{
public static class EnvDTESolutionUtility
{
/// <summary>
/// Get the list of all supported projects in the current solution. This method
/// recursively iterates through all projects.
/// </summary>
public static IEnumerable<EnvDTE.Project> GetAllEnvDTEProjects(EnvDTE.DTE dte)
{
return NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate
{
var result = await GetAllEnvDTEProjectsAsync(dte);
return result;
});
}
public static async Task<IEnumerable<EnvDTE.Project>> GetAllEnvDTEProjectsAsync(EnvDTE.DTE dte)
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
@@ -50,7 +36,7 @@ namespace NuGet.PackageManagement.VisualStudio
{
var envDTEProject = envDTEProjects.Pop();
if (EnvDTEProjectUtility.IsSupported(envDTEProject))
if (await EnvDTEProjectUtility.IsSupportedAsync(envDTEProject))
{
resultantEnvDTEProjects.Add(envDTEProject);
}
@@ -75,12 +75,12 @@ namespace NuGet.PackageManagement.VisualStudio
envDTEProject = vsmsBuildNuGetProjectSystem.VsProjectAdapter.Project;
}
if (!EnvDTEProjectUtility.IsSupported(envDTEProject))
if (!await EnvDTEProjectUtility.IsSupportedAsync(envDTEProject))
{
return false;
}
return IsProjectPackageReferenceCompatible(envDTEProject);
return await IsProjectPackageReferenceCompatibleAsync(envDTEProject);
}
private static async Task<NuGetProject> GetNuGetProject(Project envDTEProject)
@@ -92,9 +92,9 @@ namespace NuGet.PackageManagement.VisualStudio
return nuGetProject;
}
private static bool IsProjectPackageReferenceCompatible(Project project)
private static async Task<bool> IsProjectPackageReferenceCompatibleAsync(Project project)
{
var projectGuids = project.GetProjectTypeGuids();
var projectGuids = await project.GetProjectTypeGuidsAsync();
if (projectGuids.Any(t => UnupgradeableProjectTypes.Contains(t)))
{
@@ -103,7 +103,7 @@ namespace NuGet.PackageManagement.VisualStudio
// Project is supported language, and not an unsupported type
return UpgradeableProjectTypes.Contains(project.Kind) &&
projectGuids.All(projectTypeGuid => !SupportedProjectTypes.IsUnsupported(projectTypeGuid));
projectGuids.All(projectTypeGuid => !ProjectType.IsUnsupported(projectTypeGuid));
}
public static bool IsPackagesConfigSelected(IVsMonitorSelection vsMonitorSelection)
@@ -256,9 +256,9 @@ namespace NuGet.PackageManagement.VisualStudio
/// Determines if NuGet is used in the project. Currently, it is determined by checking if packages.config is part of the project
/// </summary>
/// <param name="project">The project which is checked to see if NuGet is used in it</param>
public static bool IsNuGetInUse(Project project)
public static async Task<bool> IsNuGetInUseAsync(Project project)
{
return EnvDTEProjectUtility.IsSupported(project) && File.Exists(project.GetPackagesConfigFullPath());
return await EnvDTEProjectUtility.IsSupportedAsync(project) && File.Exists(await project.GetPackagesConfigFullPathAsync());
}
}
}
@@ -31,7 +31,7 @@ namespace NuGet.PackageManagement.VisualStudio
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
// Keep track of visited projects
if (SupportsBindingRedirects(vsProjectAdapter.Project))
if (await SupportsBindingRedirectsAsync(vsProjectAdapter.Project))
{
// Get the dependentEnvDTEProjectsDictionary once here, so that, it is not called for every single project
var dependentProjectsDictionary = await vsSolutionManager.GetDependentProjectsDictionaryAsync();
@@ -45,10 +45,10 @@ namespace NuGet.PackageManagement.VisualStudio
}
}
private static bool SupportsBindingRedirects(EnvDTE.Project Project)
private static async Task<bool> SupportsBindingRedirectsAsync(EnvDTE.Project Project)
{
return (Project.Kind != null && SupportedProjectTypes.IsSupportedForBindingRedirects(Project.Kind))
&& !Project.IsWindowsStoreApp();
return (Project.Kind != null && ProjectType.IsSupportedForBindingRedirects(Project.Kind))
&& !await Project.IsWindowsStoreAppAsync();
}
private static Task AddBindingRedirectsAsync(
@@ -87,7 +87,7 @@ namespace NuGet.PackageManagement.VisualStudio
return;
}
if (SupportsBindingRedirects(vsProjectAdapter.Project))
if (await SupportsBindingRedirectsAsync(vsProjectAdapter.Project))
{
await AddBindingRedirectsAsync(vsSolutionManager, vsProjectAdapter, domain, projectAssembliesCache, frameworkMultiTargeting, nuGetProjectContext);
}
@@ -142,7 +142,7 @@ namespace NuGet.PackageManagement.VisualStudio
return redirects;
}
IEnumerable<string> assemblies = EnvDTEProjectUtility.GetAssemblyClosure(vsProjectAdapter.Project, projectAssembliesCache);
IEnumerable<string> assemblies = await EnvDTEProjectUtility.GetAssemblyClosureAsync(vsProjectAdapter.Project, projectAssembliesCache);
redirects = BindingRedirectResolver.GetBindingRedirects(assemblies, domain);
if (frameworkMultiTargeting != null)
@@ -152,7 +152,7 @@ namespace NuGet.PackageManagement.VisualStudio
}
// Create a binding redirect manager over the configuration
var manager = new BindingRedirectManager(vsProjectAdapter.Project.GetConfigurationFile(), msBuildNuGetProjectSystem);
var manager = new BindingRedirectManager(await vsProjectAdapter.Project.GetConfigurationFileAsync(), msBuildNuGetProjectSystem);
// Add the redirects
manager.AddBindingRedirects(redirects);
@@ -722,10 +722,20 @@ namespace NuGet.SolutionRestoreManager
var dte = await _asyncServiceProvider.GetDTEAsync();
var projects = dte.Solution.Projects;
return projects
.OfType<EnvDTE.Project>()
.Select(p => new ProjectInfo(p.GetFullPath(), p.Name))
.Any(p => p.CheckPackagesConfig());
var succeeded = false;
foreach (var p in projects.OfType<EnvDTE.Project>())
{
var pi = new ProjectInfo(await p.GetFullPathAsync(), p.Name);
if (pi.CheckPackagesConfig())
{
succeeded = true;
break;
}
}
return succeeded;
});
}
+9 -12
View File
@@ -427,7 +427,7 @@ namespace NuGetVSExtension
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var vsProject = project.ToVsHierarchy();
var vsProject = await project.ToVsHierarchyAsync();
var documentName = project.FullName;
// Find existing hierarchy and item id of the document window if it's
@@ -639,7 +639,7 @@ namespace NuGetVSExtension
&&
!project.IsUnloaded()
&&
EnvDTEProjectUtility.IsSupported(project))
await EnvDTEProjectUtility.IsSupportedAsync(project))
{
var windowFrame = await FindExistingWindowFrameAsync(project);
if (windowFrame == null)
@@ -907,7 +907,7 @@ namespace NuGetVSExtension
}
command.Visible = GetIsSolutionOpen() && await IsPackagesConfigBasedProjectAsync();
command.Enabled = !isConsoleBusy && IsSolutionExistsAndNotDebuggingAndNotBuilding() && HasActiveLoadedSupportedProject;
command.Enabled = !isConsoleBusy && IsSolutionExistsAndNotDebuggingAndNotBuilding() && await HasActiveLoadedSupportedProjectAsync();
});
}
@@ -932,7 +932,7 @@ namespace NuGetVSExtension
}
command.Visible = GetIsSolutionOpen() && IsPackagesConfigSelected();
command.Enabled = !isConsoleBusy && IsSolutionExistsAndNotDebuggingAndNotBuilding() && HasActiveLoadedSupportedProject;
command.Enabled = !isConsoleBusy && IsSolutionExistsAndNotDebuggingAndNotBuilding() && await HasActiveLoadedSupportedProjectAsync();
});
}
@@ -1003,7 +1003,7 @@ namespace NuGetVSExtension
command.Enabled =
IsSolutionExistsAndNotDebuggingAndNotBuilding() &&
!isConsoleBusy &&
HasActiveLoadedSupportedProject;
await HasActiveLoadedSupportedProjectAsync();
});
}
@@ -1081,14 +1081,11 @@ namespace NuGetVSExtension
/// Gets whether the current IDE has an active, supported and non-unloaded project, which is a precondition for
/// showing the Add Library Package Reference dialog
/// </summary>
private bool HasActiveLoadedSupportedProject
private async Task<bool> HasActiveLoadedSupportedProjectAsync()
{
get
{
var project = VsMonitorSelection.GetActiveProject();
return project != null && !project.IsUnloaded()
&& EnvDTEProjectUtility.IsSupported(project);
}
var project = VsMonitorSelection.GetActiveProject();
return project != null && !project.IsUnloaded()
&& await EnvDTEProjectUtility.IsSupportedAsync(project);
}
private bool ShouldMEFBeInitialized()
@@ -23,14 +23,14 @@ namespace NuGet.VisualStudio
{
public static class EnvDteProjectExtensions
{
public static IVsHierarchy ToVsHierarchy(this EnvDTE.Project project)
public static async Task<IVsHierarchy> ToVsHierarchyAsync(this EnvDTE.Project project)
{
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
IVsHierarchy hierarchy;
// Get the vs solution
var solution = ServiceLocator.GetInstance<IVsSolution>();
var solution = await ServiceLocator.GetInstanceAsync<IVsSolution>();
int hr = solution.GetProjectOfUniqueName(project.GetUniqueName(), out hierarchy);
if (hr != VSConstants.S_OK)
@@ -41,14 +41,14 @@ namespace NuGet.VisualStudio
return hierarchy;
}
public static string[] GetProjectTypeGuids(this EnvDTE.Project project)
public static async Task<string[]> GetProjectTypeGuidsAsync(this EnvDTE.Project project)
{
Verify.ArgumentIsNotNull(project, nameof(project));
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
// Get the vs hierarchy as an IVsAggregatableProject to get the project type guids
IVsHierarchy hierarchy = ToVsHierarchy(project);
IVsHierarchy hierarchy = await ToVsHierarchyAsync(project);
string[] projectTypeGuids = VsHierarchyUtility.GetProjectTypeGuids(hierarchy, project.Kind);
return projectTypeGuids;
@@ -105,9 +105,9 @@ namespace NuGet.VisualStudio
/// </summary>
/// <param name="envDTEProject">The project.</param>
/// <returns>The full path of the project directory.</returns>
public static string GetFullPath(this EnvDTE.Project envDTEProject)
public static async Task<string> GetFullPathAsync(this EnvDTE.Project envDTEProject)
{
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
Debug.Assert(envDTEProject != null);
if (IsUnloaded(envDTEProject))
@@ -125,7 +125,7 @@ namespace NuGet.VisualStudio
// until we can find one containing the full path.
// For website projects, always read FullPath from properties list
if (IsWebProject(envDTEProject))
if (await IsWebProjectAsync(envDTEProject))
{
// FullPath
var fullProjectPath = GetPropertyValue<string>(envDTEProject, FullPath);
@@ -203,12 +203,12 @@ namespace NuGet.VisualStudio
/// Returns the full path of the packages config file associated with the project.
/// </summary>
/// <param name="envDTEProject">The project.</param>
public static string GetPackagesConfigFullPath(this EnvDTE.Project envDTEProject)
public static async Task<string> GetPackagesConfigFullPathAsync(this EnvDTE.Project envDTEProject)
{
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
Debug.Assert(envDTEProject != null);
var projectDirectory = GetFullPath(envDTEProject);
var projectDirectory = await GetFullPathAsync(envDTEProject);
var packagesConfigFullPath = Path.Combine(
projectDirectory ?? string.Empty,
@@ -324,11 +324,11 @@ namespace NuGet.VisualStudio
}
// TODO: Return null for library projects
public static string GetConfigurationFile(this EnvDTE.Project envDTEProject)
public static async Task<string> GetConfigurationFileAsync(this EnvDTE.Project envDTEProject)
{
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
return IsWebProject(envDTEProject) ? WebConfig : AppConfig;
return await IsWebProjectAsync(envDTEProject) ? WebConfig : AppConfig;
}
private class PathComparer : IEqualityComparer<string>
@@ -412,10 +412,10 @@ namespace NuGet.VisualStudio
"Windows Phone OS 7.1".Equals(GetPropertyValue<string>(envDTEProject, xnaPropertyValue), StringComparison.OrdinalIgnoreCase);
}
private static bool IsWebProject(this EnvDTE.Project envDTEProject)
private static async Task<bool> IsWebProjectAsync(this EnvDTE.Project envDTEProject)
{
ThreadHelper.ThrowIfNotOnUIThread();
string[] types = envDTEProject.GetProjectTypeGuids();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
string[] types = await envDTEProject.GetProjectTypeGuidsAsync();
return types.Contains(VsProjectTypes.WebSiteProjectTypeGuid, StringComparer.OrdinalIgnoreCase) ||
types.Contains(VsProjectTypes.WebApplicationProjectTypeGuid, StringComparer.OrdinalIgnoreCase);
}
@@ -427,10 +427,10 @@ namespace NuGet.VisualStudio
return envDTEProject.Kind != null && envDTEProject.Kind.Equals(VsProjectTypes.WebSiteProjectTypeGuid, StringComparison.OrdinalIgnoreCase);
}
public static bool IsWindowsStoreApp(this EnvDTE.Project envDTEProject)
public static async Task<bool> IsWindowsStoreAppAsync(this EnvDTE.Project envDTEProject)
{
ThreadHelper.ThrowIfNotOnUIThread();
string[] types = envDTEProject.GetProjectTypeGuids();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
string[] types = await envDTEProject.GetProjectTypeGuidsAsync();
return types.Contains(VsProjectTypes.WindowsStoreProjectTypeGuid, StringComparer.OrdinalIgnoreCase);
}
@@ -2,8 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
@@ -17,7 +19,7 @@ namespace NuGet.VisualStudio
private readonly uint _vsitemid;
private readonly IVsHierarchy _hierarchy;
internal delegate int ProcessItemDelegate(VsHierarchyItem item, object callerObject, out object newCallerObject);
internal delegate Task<(int processReturn, object newCallerObject)> ProcessItemDelegateAsync(VsHierarchyItem item, object callerObject);
public IVsHierarchy VsHierarchy => _hierarchy;
@@ -32,11 +34,10 @@ namespace NuGet.VisualStudio
{
}
public static VsHierarchyItem FromDteProject(EnvDTE.Project project)
public static async Task<VsHierarchyItem> FromDteProjectAsync(EnvDTE.Project project)
{
ThreadHelper.ThrowIfNotOnUIThread();
Assumes.Present(project);
return new VsHierarchyItem(project.ToVsHierarchy());
return new VsHierarchyItem(await project.ToVsHierarchyAsync());
}
public static VsHierarchyItem FromVsHierarchy(IVsHierarchy project)
@@ -59,51 +60,49 @@ namespace NuGet.VisualStudio
internal uint VsItemID => _vsitemid;
internal bool IsExpandable()
internal async Task<bool> IsExpandableAsync()
{
ThreadHelper.ThrowIfNotOnUIThread();
var o = GetProperty(__VSHPROPID.VSHPROPID_Expandable);
var o = await GetPropertyAsync(__VSHPROPID.VSHPROPID_Expandable);
if (o is bool)
{
return (bool)o;
}
return (o is int) && (int)o != 0;
}
private object GetProperty(__VSHPROPID propid)
private async Task<object> GetPropertyAsync(__VSHPROPID propid)
{
ThreadHelper.ThrowIfNotOnUIThread();
if (TryGetProperty((int)propid, out var value))
{
return value;
}
return null;
(bool _, object value) = await TryGetPropertyAsync((int)propid);
return value;
}
private bool TryGetProperty(int propid, out object value)
private async Task<(bool found, object value)> TryGetPropertyAsync(int propid)
{
ThreadHelper.ThrowIfNotOnUIThread();
value = null;
try
{
if (_hierarchy != null)
{
_hierarchy.GetProperty(_vsitemid, propid, out value);
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
_hierarchy.GetProperty(_vsitemid, propid, out object value);
return (true, value);
}
}
catch (Exception e)
{
if (e.IsCritical())
{
throw;
}
return true;
}
catch
{
return false;
// Ignore.
}
return (false, null);
}
internal int WalkDepthFirst(bool fVisible, ProcessItemDelegate processCallback, object callerObject)
internal async Task<int> WalkDepthFirstAsync(bool fVisible, ProcessItemDelegateAsync processCallbackAsync, object callerObject)
{
ThreadHelper.ThrowIfNotOnUIThread();
//
// TODO Need to see what to do if this is a sub project
//
@@ -111,13 +110,12 @@ namespace NuGet.VisualStudio
// Guid nodeGuid;
// if (hier.GetGuidProperty(_vsitemid, (int)__VSHPROPID.VSHPROPID_TypeGuid, out nodeGuid) != 0)
if (processCallback == null)
if (processCallbackAsync == null)
{
return 0;
}
object newCallerObject;
int processReturn = processCallback(this, callerObject, out newCallerObject);
(int processReturn, object newCallerObject) = await processCallbackAsync(this, callerObject);
if (processReturn != 0)
{
// Callback says to skip (1) or stop (-1)
@@ -132,44 +130,43 @@ namespace NuGet.VisualStudio
}
// Walk children if there are any
if (IsExpandable())
if (await IsExpandableAsync())
{
VsHierarchyItem child = GetFirstChild(fVisible);
VsHierarchyItem child = await GetFirstChildAsync(fVisible);
while (child != null)
{
object isNonMemberItemValue = child.GetProperty(__VSHPROPID.VSHPROPID_IsNonMemberItem);
object isNonMemberItemValue = await child.GetPropertyAsync(__VSHPROPID.VSHPROPID_IsNonMemberItem);
// Some project systems (e.g. F#) don't support querying for the VSHPROPID_IsNonMemberItem property.
// In that case, we treat this child as belonging to the project
bool isMemberOfProject = isNonMemberItemValue == null || (bool)isNonMemberItemValue == false;
if (isMemberOfProject)
{
int returnVal = child.WalkDepthFirst(fVisible, processCallback, newCallerObject);
int returnVal = await child.WalkDepthFirstAsync(fVisible, processCallbackAsync, newCallerObject);
if (returnVal == -1)
{
return returnVal;
}
}
child = child.GetNextSibling(fVisible);
child = await child.GetNextSiblingAsync(fVisible);
}
}
return 0;
}
internal VsHierarchyItem GetNextSibling(bool fVisible)
internal async Task<VsHierarchyItem> GetNextSiblingAsync(bool fVisible)
{
ThreadHelper.ThrowIfNotOnUIThread();
uint childId = GetNextSiblingId(fVisible);
uint childId = await GetNextSiblingIdAsync(fVisible);
if (childId != VSConstants.VSITEMID_NIL)
{
return new VsHierarchyItem(_hierarchy, childId);
}
return null;
}
internal uint GetNextSiblingId(bool fVisible)
internal async Task<uint> GetNextSiblingIdAsync(bool fVisible)
{
ThreadHelper.ThrowIfNotOnUIThread();
object o = GetProperty(fVisible ? __VSHPROPID.VSHPROPID_NextVisibleSibling : __VSHPROPID.VSHPROPID_NextSibling);
object o = await GetPropertyAsync(fVisible ? __VSHPROPID.VSHPROPID_NextVisibleSibling : __VSHPROPID.VSHPROPID_NextSibling);
if (o is int)
{
@@ -179,33 +176,35 @@ namespace NuGet.VisualStudio
{
return (uint)o;
}
return VSConstants.VSITEMID_NIL;
}
internal VsHierarchyItem GetFirstChild(bool fVisible)
internal async Task<VsHierarchyItem> GetFirstChildAsync(bool fVisible)
{
ThreadHelper.ThrowIfNotOnUIThread();
uint childId = GetFirstChildId(fVisible);
uint childId = await GetFirstChildIdAsync(fVisible);
if (childId != VSConstants.VSITEMID_NIL)
{
return new VsHierarchyItem(_hierarchy, childId);
}
return null;
}
internal uint GetFirstChildId(bool fVisible)
internal async Task<uint> GetFirstChildIdAsync(bool fVisible)
{
ThreadHelper.ThrowIfNotOnUIThread();
object o = GetProperty(fVisible ? __VSHPROPID.VSHPROPID_FirstVisibleChild : __VSHPROPID.VSHPROPID_FirstChild);
object o = await GetPropertyAsync(fVisible ? __VSHPROPID.VSHPROPID_FirstVisibleChild : __VSHPROPID.VSHPROPID_FirstChild);
if (o is int)
{
return unchecked((uint)((int)o));
}
if (o is uint)
{
return (uint)o;
}
return VSConstants.VSITEMID_NIL;
}
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
@@ -31,25 +32,23 @@ namespace NuGet.VisualStudio
return projectPath;
}
public static bool IsSupported(IVsHierarchy hierarchy, string projectTypeGuid)
public static async Task<bool> IsSupportedAsync(IVsHierarchy hierarchy, string projectTypeGuid)
{
ThreadHelper.ThrowIfNotOnUIThread();
if (IsProjectCapabilityCompliant(hierarchy))
if (await IsProjectCapabilityCompliantAsync(hierarchy))
{
return true;
}
return !string.IsNullOrEmpty(projectTypeGuid) && SupportedProjectTypes.IsSupported(projectTypeGuid) && !HasUnsupportedProjectCapability(hierarchy);
return !string.IsNullOrEmpty(projectTypeGuid) && ProjectType.IsSupported(projectTypeGuid) && !HasUnsupportedProjectCapability(hierarchy);
}
/// <summary>Check if this project appears to support NuGet.</summary>
/// <param name="hierarchy">IVsHierarchy representing the project in the solution.</param>
/// <returns>True if NuGet should enable this project, false if NuGet should ignore the project.</returns>
/// <remarks>The project may be packages.config or PackageReference. This method does not tell you which.</remarks>
public static bool IsProjectCapabilityCompliant(IVsHierarchy hierarchy)
public static async Task<bool> IsProjectCapabilityCompliantAsync(IVsHierarchy hierarchy)
{
ThreadHelper.ThrowIfNotOnUIThread();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
// NOTE: (AssemblyReferences + DeclaredSourceItems + UserSourceItems) exists solely for compatibility reasons
// with existing custom CPS-based projects that existed before "PackageReferences" capability was introduced.
@@ -126,7 +125,7 @@ namespace NuGet.VisualStudio
foreach (var project in projects.Cast<EnvDTE.Project>())
{
var expandedNodes =
GetExpandedProjectHierarchyItems(project);
await GetExpandedProjectHierarchyItemsAsync(project);
Debug.Assert(!results.ContainsKey(project.GetUniqueName()));
results[project.GetUniqueName()] =
new HashSet<VsHierarchyItem>(expandedNodes);
@@ -150,52 +149,49 @@ namespace NuGet.VisualStudio
&&
expandedNodes != null)
{
CollapseProjectHierarchyItems(project, expandedNodes);
await CollapseProjectHierarchyItemsAsync(project, expandedNodes);
}
}
}
private static ICollection<VsHierarchyItem> GetExpandedProjectHierarchyItems(EnvDTE.Project project)
private static async Task<ICollection<VsHierarchyItem>> GetExpandedProjectHierarchyItemsAsync(EnvDTE.Project project)
{
ThreadHelper.ThrowIfNotOnUIThread();
var projectHierarchyItem = VsHierarchyItem.FromDteProject(project);
var projectHierarchyItem = await VsHierarchyItem.FromDteProjectAsync(project);
var solutionExplorerWindow = GetSolutionExplorerHierarchyWindow();
if (solutionExplorerWindow == null)
{
// If the solution explorer is collapsed since opening VS, this value is null. In such a case, simply exit early.
return new VsHierarchyItem[0];
return Array.Empty<VsHierarchyItem>();
}
var expandedItems = new List<VsHierarchyItem>();
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
// processCallback return values:
// 0 continue,
// 1 don't recurse into,
// -1 stop
projectHierarchyItem.WalkDepthFirst(
await projectHierarchyItem.WalkDepthFirstAsync(
fVisible: true,
processCallback:
(VsHierarchyItem vsItem, object callerObject, out object newCallerObject) =>
processCallbackAsync:
async (VsHierarchyItem vsItem, object callerObject) =>
{
newCallerObject = null;
if (IsVsHierarchyItemExpanded(vsItem, solutionExplorerWindow))
if (await IsVsHierarchyItemExpandedAsync(vsItem, solutionExplorerWindow))
{
expandedItems.Add(vsItem);
}
return 0;
return (0, null);
},
callerObject: null);
return expandedItems;
}
private static void CollapseProjectHierarchyItems(EnvDTE.Project project, ISet<VsHierarchyItem> ignoredHierarcyItems)
private static async Task CollapseProjectHierarchyItemsAsync(EnvDTE.Project project, ISet<VsHierarchyItem> ignoredHierarcyItems)
{
ThreadHelper.ThrowIfNotOnUIThread();
var projectHierarchyItem = VsHierarchyItem.FromDteProject(project);
var projectHierarchyItem = await VsHierarchyItem.FromDteProjectAsync(project);
var solutionExplorerWindow = GetSolutionExplorerHierarchyWindow();
if (solutionExplorerWindow == null)
@@ -208,39 +204,35 @@ namespace NuGet.VisualStudio
// 0 continue,
// 1 don't recurse into,
// -1 stop
projectHierarchyItem.WalkDepthFirst(
await projectHierarchyItem.WalkDepthFirstAsync(
fVisible: true,
processCallback:
(VsHierarchyItem currentHierarchyItem, object callerObject, out object newCallerObject) =>
processCallbackAsync:
async (VsHierarchyItem currentHierarchyItem, object callerObject) =>
{
newCallerObject = null;
if (!ignoredHierarcyItems.Contains(currentHierarchyItem))
{
CollapseVsHierarchyItem(currentHierarchyItem, solutionExplorerWindow);
await CollapseVsHierarchyItemAsync(currentHierarchyItem, solutionExplorerWindow);
}
return 0;
return (0, null);
},
callerObject: null);
}
private static void CollapseVsHierarchyItem(VsHierarchyItem vsHierarchyItem, IVsUIHierarchyWindow vsHierarchyWindow)
private static async Task CollapseVsHierarchyItemAsync(VsHierarchyItem vsHierarchyItem, IVsUIHierarchyWindow vsHierarchyWindow)
{
ThreadHelper.ThrowIfNotOnUIThread();
if (vsHierarchyItem == null
|| vsHierarchyWindow == null)
{
return;
}
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
vsHierarchyWindow.ExpandItem(AsVsUIHierarchy(vsHierarchyItem), vsHierarchyItem.VsItemID, EXPANDFLAGS.EXPF_CollapseFolder);
}
private static bool IsVsHierarchyItemExpanded(VsHierarchyItem hierarchyItem, IVsUIHierarchyWindow uiWindow)
private static async Task<bool> IsVsHierarchyItemExpandedAsync(VsHierarchyItem hierarchyItem, IVsUIHierarchyWindow uiWindow)
{
ThreadHelper.ThrowIfNotOnUIThread();
if (!hierarchyItem.IsExpandable())
if (!await hierarchyItem.IsExpandableAsync())
{
return false;
}
@@ -248,6 +240,7 @@ namespace NuGet.VisualStudio
const uint expandedStateMask = (uint)__VSHIERARCHYITEMSTATE.HIS_Expanded;
uint itemState;
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
uiWindow.GetItemState(AsVsUIHierarchy(hierarchyItem), hierarchyItem.VsItemID, expandedStateMask, out itemState);
return ((__VSHIERARCHYITEMSTATE)itemState == __VSHIERARCHYITEMSTATE.HIS_Expanded);
}
@@ -24,7 +24,7 @@ namespace NuGet.VisualStudio
/// <summary>
/// MSBuildProjectExtensionsPath project property (e.g. c:\projFoo\obj)
/// </summary>
string MSBuildProjectExtensionsPath { get; }
Task<string> GetMSBuildProjectExtensionsPathAsync();
IProjectBuildProperties BuildProperties { get; }
@@ -36,7 +36,7 @@ namespace NuGet.VisualStudio
bool IsDeferred { get; }
bool IsSupported { get; }
Task<bool> IsSupportedAsync();
/// <summary>
/// Comma or Semicolon separated list of NU* diagnostic codes e.g. NU1000,NU1001
@@ -58,7 +58,7 @@ namespace NuGet.VisualStudio
/// <summary>
/// Full path to a parent directory containing project file.
/// </summary>
string ProjectDirectory { get; }
Task<string> GetProjectDirectoryAsync();
string ProjectName { get; }
@@ -0,0 +1,91 @@
// 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.IO;
using System.Linq;
namespace NuGet.VisualStudio
{
public static class ProjectType
{
private static readonly HashSet<string> Supported = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
VsProjectTypes.WebSiteProjectTypeGuid,
VsProjectTypes.CsharpProjectTypeGuid,
VsProjectTypes.VbProjectTypeGuid,
VsProjectTypes.CppProjectTypeGuid,
VsProjectTypes.JsProjectTypeGuid,
VsProjectTypes.FsharpProjectTypeGuid,
VsProjectTypes.NemerleProjectTypeGuid,
VsProjectTypes.WixProjectTypeGuid,
VsProjectTypes.SynergexProjectTypeGuid,
VsProjectTypes.NomadForVisualStudioProjectTypeGuid,
VsProjectTypes.TDSProjectTypeGuid,
VsProjectTypes.DxJsProjectTypeGuid,
VsProjectTypes.DeploymentProjectTypeGuid,
VsProjectTypes.CosmosProjectTypeGuid,
VsProjectTypes.ManagementPackProjectTypeGuid,
};
private static readonly HashSet<string> Unsupported = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
VsProjectTypes.LightSwitchProjectTypeGuid,
VsProjectTypes.InstallShieldLimitedEditionTypeGuid
};
// List of project types that cannot have binding redirects added
private static readonly HashSet<string> UnsupportedProjectTypesForBindingRedirects = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
VsProjectTypes.WixProjectTypeGuid,
VsProjectTypes.JsProjectTypeGuid,
VsProjectTypes.NemerleProjectTypeGuid,
VsProjectTypes.CppProjectTypeGuid,
VsProjectTypes.SynergexProjectTypeGuid,
VsProjectTypes.NomadForVisualStudioProjectTypeGuid,
VsProjectTypes.DxJsProjectTypeGuid,
VsProjectTypes.CosmosProjectTypeGuid,
};
// List of project types that cannot have references added to them
private static readonly HashSet<string> UnsupportedProjectTypesForAddingReferences = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
VsProjectTypes.WixProjectTypeGuid,
VsProjectTypes.CppProjectTypeGuid,
};
private static readonly HashSet<string> UnsupportedProjectExtension = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
".metaproj",
".shproj",
".vcxitems",
".sqlproj"
};
public static bool IsSupported(string projectKind)
{
return Supported.Contains(projectKind);
}
public static bool IsUnsupported(string projectKind)
{
return Unsupported.Contains(projectKind);
}
public static bool IsSupportedForBindingRedirects(string projectKind)
{
return !UnsupportedProjectTypesForBindingRedirects.Contains(projectKind, StringComparer.OrdinalIgnoreCase);
}
public static bool IsSupportedForAddingReferences(string projectKind)
{
return !UnsupportedProjectTypesForAddingReferences.Contains(projectKind, StringComparer.OrdinalIgnoreCase);
}
public static bool IsSupportedProjectExtension(string projectPath)
{
return !UnsupportedProjectExtension.Contains(Path.GetExtension(projectPath));
}
}
}
@@ -1,92 +0,0 @@
// 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.IO;
using System.Linq;
using NuGet.VisualStudio;
namespace NuGet.VisualStudio
{
public static class SupportedProjectTypes
{
private static readonly HashSet<string> _supportedProjectTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
VsProjectTypes.WebSiteProjectTypeGuid,
VsProjectTypes.CsharpProjectTypeGuid,
VsProjectTypes.VbProjectTypeGuid,
VsProjectTypes.CppProjectTypeGuid,
VsProjectTypes.JsProjectTypeGuid,
VsProjectTypes.FsharpProjectTypeGuid,
VsProjectTypes.NemerleProjectTypeGuid,
VsProjectTypes.WixProjectTypeGuid,
VsProjectTypes.SynergexProjectTypeGuid,
VsProjectTypes.NomadForVisualStudioProjectTypeGuid,
VsProjectTypes.TDSProjectTypeGuid,
VsProjectTypes.DxJsProjectTypeGuid,
VsProjectTypes.DeploymentProjectTypeGuid,
VsProjectTypes.CosmosProjectTypeGuid,
VsProjectTypes.ManagementPackProjectTypeGuid,
};
private static readonly HashSet<string> _unsupportedProjectTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
VsProjectTypes.LightSwitchProjectTypeGuid,
VsProjectTypes.InstallShieldLimitedEditionTypeGuid
};
// List of project types that cannot have binding redirects added
private static readonly string[] _unsupportedProjectTypesForBindingRedirects =
{
VsProjectTypes.WixProjectTypeGuid,
VsProjectTypes.JsProjectTypeGuid,
VsProjectTypes.NemerleProjectTypeGuid,
VsProjectTypes.CppProjectTypeGuid,
VsProjectTypes.SynergexProjectTypeGuid,
VsProjectTypes.NomadForVisualStudioProjectTypeGuid,
VsProjectTypes.DxJsProjectTypeGuid,
VsProjectTypes.CosmosProjectTypeGuid,
};
// List of project types that cannot have references added to them
private static readonly string[] _unsupportedProjectTypesForAddingReferences =
{
VsProjectTypes.WixProjectTypeGuid,
VsProjectTypes.CppProjectTypeGuid,
};
private static readonly HashSet<string> _unsupportedProjectExtension = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
".metaproj",
".shproj",
".vcxitems",
".sqlproj"
};
public static bool IsSupported(string projectKind)
{
return _supportedProjectTypes.Contains(projectKind);
}
public static bool IsUnsupported(string projectKind)
{
return _unsupportedProjectTypes.Contains(projectKind);
}
public static bool IsSupportedForBindingRedirects(string projectKind)
{
return !_unsupportedProjectTypesForBindingRedirects.Contains(projectKind, StringComparer.OrdinalIgnoreCase);
}
public static bool IsSupportedForAddingReferences(string projectKind)
{
return !_unsupportedProjectTypesForAddingReferences.Contains(projectKind, StringComparer.OrdinalIgnoreCase);
}
public static bool IsSupportedProjectExtension(string projectPath)
{
return !_unsupportedProjectExtension.Contains(Path.GetExtension(projectPath));
}
}
}
@@ -70,7 +70,7 @@ namespace NuGet.VisualStudio
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
IVsHierarchy vsHierarchy = project.ToVsHierarchy();
IVsHierarchy vsHierarchy = await project.ToVsHierarchyAsync();
if (vsHierarchy != null &&
VsHierarchyUtility.IsCPSCapabilityCompliant(vsHierarchy))
{
@@ -325,7 +325,15 @@ namespace NuGet.VisualStudio
private async Task<IEnumerable<Project>> GetProjectsInSolutionAsync(DTE dte)
{
IEnumerable<Project> allProjects = await EnvDTESolutionUtility.GetAllEnvDTEProjectsAsync(dte);
IEnumerable<Project> supportedProjects = allProjects.Where(EnvDTEProjectUtility.IsSupported);
var supportedProjects = new List<Project>();
foreach (Project project in allProjects)
{
if (await EnvDTEProjectUtility.IsSupportedAsync(project))
{
supportedProjects.Add(project);
}
}
return supportedProjects;
}
Binary file not shown.
@@ -53,8 +53,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Directory.CreateDirectory(testMSBuildProjectExtensionsPath);
var projectAdapter = Mock.Of<IVsProjectAdapter>();
Mock.Get(projectAdapter)
.SetupGet(x => x.MSBuildProjectExtensionsPath)
.Returns(testMSBuildProjectExtensionsPath);
.Setup(x => x.GetMSBuildProjectExtensionsPathAsync())
.Returns(Task.FromResult(testMSBuildProjectExtensionsPath));
var testProject = new LegacyPackageReferenceProject(
projectAdapter,
@@ -72,7 +72,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
// Verify
Mock.Get(projectAdapter)
.VerifyGet(x => x.MSBuildProjectExtensionsPath, Times.AtLeastOnce);
.Verify(x => x.GetMSBuildProjectExtensionsPathAsync(), Times.AtLeastOnce);
}
}
@@ -107,8 +107,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Directory.CreateDirectory(testMSBuildProjectExtensionsPath);
var projectAdapter = Mock.Of<IVsProjectAdapter>();
Mock.Get(projectAdapter)
.SetupGet(x => x.MSBuildProjectExtensionsPath)
.Returns(testMSBuildProjectExtensionsPath);
.Setup(x => x.GetMSBuildProjectExtensionsPathAsync())
.Returns(Task.FromResult(testMSBuildProjectExtensionsPath));
Mock.Get(projectAdapter)
.SetupGet(x => x.FullProjectPath)
@@ -130,7 +130,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
// Verify
Mock.Get(projectAdapter)
.VerifyGet(x => x.MSBuildProjectExtensionsPath, Times.AtLeastOnce);
.Verify(x => x.GetMSBuildProjectExtensionsPathAsync(), Times.AtLeastOnce);
}
}
@@ -165,8 +165,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Directory.CreateDirectory(testMSBuildProjectExtensionsPath);
var projectAdapter = Mock.Of<IVsProjectAdapter>();
Mock.Get(projectAdapter)
.SetupGet(x => x.MSBuildProjectExtensionsPath)
.Returns(testMSBuildProjectExtensionsPath);
.Setup(x => x.GetMSBuildProjectExtensionsPathAsync())
.Returns(Task.FromResult(testMSBuildProjectExtensionsPath));
Mock.Get(projectAdapter)
.SetupGet(x => x.FullProjectPath)
@@ -186,7 +186,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
// Verify
Mock.Get(projectAdapter)
.VerifyGet(x => x.MSBuildProjectExtensionsPath, Times.AtLeastOnce);
.Verify(x => x.GetMSBuildProjectExtensionsPathAsync(), Times.AtLeastOnce);
}
}
@@ -1203,8 +1203,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test
var testMSBuildProjectExtensionsPath = Path.Combine(fullPath, "obj");
Directory.CreateDirectory(testMSBuildProjectExtensionsPath);
projectAdapter
.Setup(x => x.MSBuildProjectExtensionsPath)
.Returns(testMSBuildProjectExtensionsPath);
.Setup(x => x.GetMSBuildProjectExtensionsPathAsync())
.Returns(Task.FromResult(testMSBuildProjectExtensionsPath));
return projectAdapter.Object;
}
@@ -361,8 +361,9 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.True(File.Exists(projectLockFilePath));
// delete existing restore output files
File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json"));
File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName));
string msBuildProjectExtensionsPath = await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync();
File.Delete(Path.Combine(msBuildProjectExtensionsPath, "project.assets.json"));
File.Delete(Path.Combine(msBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName));
// add a new package
var newPackageContext = new SimpleTestPackageContext("packageA", "1.0.1");
@@ -390,7 +391,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.False(restoreSummary.NoOpRestore);
}
var lockFilePath = Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json");
var lockFilePath = Path.Combine(msBuildProjectExtensionsPath, "project.assets.json");
Assert.True(File.Exists(lockFilePath));
var lockFile = new LockFileFormat().Read(lockFilePath);
@@ -490,9 +491,11 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.False(restoreSummary.NoOpRestore);
}
string msBuildProjectExtensionsPath = await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync();
// Initial asserts
Assert.True(File.Exists(projectLockFilePath));
var assetsFilePath = Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json");
var assetsFilePath = Path.Combine(msBuildProjectExtensionsPath, "project.assets.json");
Assert.True(File.Exists(assetsFilePath));
// Assert that there is no warning logged into assets file
@@ -500,7 +503,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.False(assetsFile.LogMessages.Any());
// delete existing restore output files
File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json"));
File.Delete(Path.Combine(msBuildProjectExtensionsPath, "project.assets.json"));
// install a new package
projectServices.SetupInstalledPackages(
@@ -867,8 +870,9 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.True(File.Exists(projectLockFilePath));
// delete existing restore output files
File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json"));
File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName));
string msBuildProjectExtensionsPath = await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync();
File.Delete(Path.Combine(msBuildProjectExtensionsPath, "project.assets.json"));
File.Delete(Path.Combine(msBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName));
// clean packages folder
Directory.Delete(testSolutionManager.GlobalPackagesFolder, true);
@@ -1001,7 +1005,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.True(File.Exists(projectLockFilePath));
// delete existing restore output files
File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json"));
File.Delete(Path.Combine(await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json"));
// clean packages folder
Directory.Delete(testSolutionManager.GlobalPackagesFolder, true);
@@ -1153,7 +1157,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
sourceRepositoryProvider.GetRepositories(), sourceRepositoryProvider.GetRepositories(), CancellationToken.None);
// Assert
var lockFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json");
var lockFilePath = Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json");
Assert.True(File.Exists(lockFilePath));
}
@@ -1225,7 +1229,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
sourceRepositoryProvider.GetRepositories(), sourceRepositoryProvider.GetRepositories(), CancellationToken.None);
// Assert
var assetsFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json");
var assetsFilePath = Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json");
Assert.True(File.Exists(assetsFilePath));
var assetsFile = new LockFileFormat().Read(assetsFilePath);
@@ -1346,7 +1350,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
CancellationToken.None);
// Assert
var assetsFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json");
var assetsFilePath = Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json");
Assert.True(File.Exists(assetsFilePath));
var assetsFile = new LockFileFormat().Read(assetsFilePath);
@@ -1827,7 +1831,9 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.True(File.Exists(projectLockFilePath));
var lockFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json");
string msBuildProjectExtensionsPathA = await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync();
var lockFilePath = Path.Combine(msBuildProjectExtensionsPathA, "project.assets.json");
Assert.True(File.Exists(lockFilePath));
var lockFile = new LockFileFormat().Read(lockFilePath);
@@ -1835,8 +1841,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.Equal("1.0.0", resolvedVersion.ToNormalizedString());
// delete existing restore output files
File.Delete(Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json"));
File.Delete(Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName));
File.Delete(Path.Combine(msBuildProjectExtensionsPathA, "project.assets.json"));
File.Delete(Path.Combine(msBuildProjectExtensionsPathA, NoOpRestoreUtilities.NoOpCacheFileName));
//clear packageA 1.0.0 from global packages folder
var packageAPath = Path.Combine(testSolutionManager.GlobalPackagesFolder, "packagea", "1.0.0");
@@ -2008,8 +2014,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.Equal(PackageDependencyType.Project, lockFile.Targets[0].Dependencies[1].Type);
// Act
File.Delete(Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName));
File.Delete(Path.Combine(vsProjectAdapterB.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName));
File.Delete(Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), NoOpRestoreUtilities.NoOpCacheFileName));
File.Delete(Path.Combine(await vsProjectAdapterB.GetMSBuildProjectExtensionsPathAsync(), NoOpRestoreUtilities.NoOpCacheFileName));
restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync(
testSolutionManager,
@@ -2156,7 +2162,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.False(restoreSummary.NoOpRestore);
}
var assetsFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json");
var assetsFilePath = Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json");
Assert.True(File.Exists(assetsFilePath));
var assetsFile = new LockFileFormat().Read(assetsFilePath);
@@ -2276,7 +2282,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
Assert.False(restoreSummary.NoOpRestore);
}
var assetsFilePath = Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json");
var assetsFilePath = Path.Combine(await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json");
Assert.True(File.Exists(assetsFilePath));
var assetsFile = new LockFileFormat().Read(assetsFilePath);
@@ -54,12 +54,9 @@ namespace NuGet.PackageManagement.VisualStudio.Test
}
}
public string MSBuildProjectExtensionsPath
public async Task<string> GetMSBuildProjectExtensionsPathAsync()
{
get
{
return Path.Combine(ProjectDirectory, "obj");
}
return Path.Combine(await GetProjectDirectoryAsync(), "obj");
}
public IProjectBuildProperties BuildProperties { get; } = Mock.Of<IProjectBuildProperties>();
@@ -72,7 +69,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
public bool IsDeferred => false;
public bool IsSupported => true;
public Task<bool> IsSupportedAsync() => Task.FromResult(true);
public string NoWarn
{
@@ -100,13 +97,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test
}
}
public string ProjectDirectory
{
get
{
return Path.GetDirectoryName(FullProjectPath);
}
}
public Task<string> GetProjectDirectoryAsync() => Task.FromResult(Path.GetDirectoryName(FullProjectPath));
public string ProjectName => ProjectNames.ShortName;
@@ -156,10 +156,13 @@ namespace API.Test
});
}
public static async Task<IVsProjectJsonToPackageReferenceMigrateResult> MigrateJsonProject(string projectName)
public static IVsProjectJsonToPackageReferenceMigrateResult MigrateJsonProject(string projectName)
{
var migrator = ServiceLocator.GetComponent<IVsProjectJsonToPackageReferenceMigrator>();
return (IVsProjectJsonToPackageReferenceMigrateResult)await migrator.MigrateProjectJsonToPackageReferenceAsync(projectName);
return ThreadHelper.JoinableTaskFactory.Run(async () =>
{
var migrator = ServiceLocator.GetComponent<IVsProjectJsonToPackageReferenceMigrator>();
return (IVsProjectJsonToPackageReferenceMigrateResult)await migrator.MigrateProjectJsonToPackageReferenceAsync(projectName);
});
}
public static bool IsFileExistsInProject(string projectUniqueName, string filePath)
@@ -178,7 +181,7 @@ namespace API.Test
if (!string.IsNullOrEmpty(solutionProjectPath) &&
PathUtility.GetStringComparerBasedOnOS().Equals(solutionProjectPath, projectUniqueName))
{
return await EnvDTEProjectUtility.ContainsFile(project, filePath);
return await EnvDTEProjectUtility.ContainsFileAsync(project, filePath);
}
}