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

Rewrite dependencies tree #9008

Merged
merged 9 commits into from
May 16, 2023
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
289 changes: 140 additions & 149 deletions docs/repo/dependencies-node-roadmap.md
drewnoakes marked this conversation as resolved.
Show resolved Hide resolved

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions eng/imports/HostAgnostic.props
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@

<!-- 3rd party -->
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="IsExternalInit" />
drewnoakes marked this conversation as resolved.
Show resolved Hide resolved

<!-- Host-Agnostic Visual Studio -->
<PackageReference Include="Microsoft.VisualStudio.ImageCatalog" />
Expand Down
1 change: 1 addition & 0 deletions eng/imports/Packages.targets
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@

<!-- 3rd party -->
<PackageReference Update="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Update="IsExternalInit" Version="1.0.3" PrivateAssets="all" />

<!-- Tests -->
<PackageReference Update="Moq" Version="4.16.1" />
Expand Down
1 change: 1 addition & 0 deletions src/Common/BannedSymbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ F:Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_UNKNOWNGROUP;Use HRes
T:Microsoft.VisualStudio.Shell.ThreadHelper;Import JoinableTaskContext if inside a MEF component for unit testing purposes

T:Microsoft.VisualStudio.ProjectSystem.Properties.StandardRuleDataflowLinkOptions;Use DataflowOption.WithRuleNames to avoid boilerplate initialization
T:Microsoft.VisualStudio.ProjectSystem.Properties.JointRuleDataflowLinkOptions;Use DataflowOption.WithJointRuleNames to avoid boilerplate initialization
T:System.Threading.Tasks.Dataflow.DataflowLinkOptions;Use DataflowOption.PropagateCompletion to avoid boilerplate initialization

M:Microsoft.VisualStudio.ProjectSystem.OnceInitializedOnceDisposed.Initialize();Did you mean EnsureInitialized?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using Microsoft.VisualStudio.IO;
using Microsoft.VisualStudio.ProjectSystem.Input;
using Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies;
using Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Input.Commands
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using Microsoft.VisualStudio.IO;
using Microsoft.VisualStudio.ProjectSystem.Input;
using Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies;
using Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Input.Commands
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ async Task OnSlicesChanged(IProjectVersionedValue<(ConfiguredProject ActiveConfi

firstWorkspace ??= workspace;

workspace.IsPrimary = IsPrimaryActiveSlice(slice, activeProjectConfiguration);
workspace.IsPrimary = slice.IsPrimaryActiveSlice(activeProjectConfiguration);

if (workspace.IsPrimary)
{
Expand Down Expand Up @@ -230,26 +230,6 @@ async Task OnSlicesChanged(IProjectVersionedValue<(ConfiguredProject ActiveConfi
_primaryWorkspace = firstWorkspace;
}
}

static bool IsPrimaryActiveSlice(ProjectConfigurationSlice slice, ProjectConfiguration activeProjectConfiguration)
{
// If all slice dimensions are present with the same value in the configuration, then this is a match.
foreach ((string name, string value) in slice.Dimensions)
{
if (activeProjectConfiguration.Dimensions.TryGetValue(name, out string activeValue) &&
StringComparers.ConfigurationDimensionValues.Equals(value, activeValue))
{
continue;
drewnoakes marked this conversation as resolved.
Show resolved Hide resolved
}

// The dimension's value is either unknown, or the value differs. This is not a match.
return false;
}

// All dimensions in the slice match the project configuration.
// If the slice's configuration is empty, we also return true.
return true;
}
}

#region IWorkspaceWriter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal sealed class UpdateHandlers : IDisposable
public ImmutableArray<IProjectEvaluationHandler> EvaluationHandlers { get; }
public ImmutableArray<ISourceItemsHandler> SourceItemHandlers { get; }

public ImmutableArray<string> EvaluationRules { get; }
public ImmutableHashSet<string> EvaluationRules { get; }

private readonly ExportLifetimeContext<IWorkspaceUpdateHandler>[] _lifetimes;

Expand All @@ -35,8 +35,7 @@ public UpdateHandlers(ExportFactory<IWorkspaceUpdateHandler>[] factories)
EvaluationRules = EvaluationHandlers
.Select(handler => handler.ProjectEvaluationRule) // Each handler specifies the evaluation rule it wants
.Append(ConfigurationGeneral.SchemaName) // Needed when creating IWorkspaceProjectContext
.Distinct(StringComparers.RuleNames)
.ToImmutableArray();
.ToImmutableHashSet(StringComparers.RuleNames);

ImmutableArray<T> Create<T>()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using Microsoft.VisualStudio.ProjectSystem.Utilities;
using Microsoft.VisualStudio.Shell;

using Flags = Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies.DependencyTreeFlags;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedCollections
{
/// <summary>
Expand Down Expand Up @@ -44,7 +46,7 @@ public DependenciesTreeProjectSearchContext(

IProjectTree targetRootNode;

if (_dependenciesNode.FindChildWithFlags(DependencyTreeFlags.TargetNode) is null)
if (_dependenciesNode.FindChildWithFlags(Flags.TargetNode) is null)
{
// Tree does not show any target nodes
targetRootNode = _dependenciesNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using Microsoft.VisualStudio.Threading;
using Microsoft.VisualStudio.Utilities;

using Flags = Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies.DependencyTreeFlags;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedCollections
{
/// <summary>
Expand Down Expand Up @@ -95,7 +97,7 @@ Task SearchSolutionAsync()
async Task SearchProjectAsync(UnconfiguredProject unconfiguredProject)
{
IUnconfiguredProjectVsServices? projectVsServices = unconfiguredProject.Services.ExportProvider.GetExportedValue<IUnconfiguredProjectVsServices>();
IProjectTree? dependenciesNode = projectVsServices?.ProjectTree.CurrentTree?.FindChildWithFlags(DependencyTreeFlags.DependenciesRootNode);
IProjectTree? dependenciesNode = projectVsServices?.ProjectTree.CurrentTree?.FindChildWithFlags(Flags.DependenciesRootNode);

if (projectVsServices is not null && dependenciesNode is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

using Flags = Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies.DependencyTreeFlags;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedCollections
{
/// <summary>
Expand All @@ -24,7 +26,7 @@ internal static class IVsHierarchyItemExtensions
/// <returns><see langword="true"/> if the target was found, otherwise <see langword="false"/>.</returns>
public static bool TryFindTarget(this IVsHierarchyItem item, [NotNullWhen(returnValue: true)] out string? target)
{
s_targetFlagsRegex ??= new Regex(@"^(?=.*\b" + nameof(DependencyTreeFlags.TargetNode) + @"\b)(?=.*\$TFM:(?<target>[^ ]+)\b).*$", RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.CultureInvariant);
s_targetFlagsRegex ??= new Regex(@"^(?=.*\b" + nameof(Flags.TargetNode) + @"\b)(?=.*\$TFM:(?<target>[^ ]+)\b).*$", RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.CultureInvariant);

for (IVsHierarchyItem? parent = item; parent is not null; parent = parent.Parent)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Utilities;

using Flags = Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies.DependencyTreeFlags;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedCollections.Implementation
{
[AppliesToProject(ProjectCapability.DependenciesTree)]
Expand All @@ -19,7 +21,7 @@ internal sealed class FrameworkReferenceAssemblyAttachedCollectionSourceProvider

[ImportingConstructor]
public FrameworkReferenceAssemblyAttachedCollectionSourceProvider(IRelationProvider relationProvider)
: base(DependencyTreeFlags.FrameworkDependency)
: base(Flags.FrameworkDependency)
{
_relationProvider = relationProvider;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// 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.md file in the project root for more information.

using Flags = Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies.DependencyTreeFlags;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.Commands
{
/// <summary>
Expand Down Expand Up @@ -35,71 +37,71 @@ public bool TryGetContextMenu(IProjectTree projectItem, out Guid menuCommandGuid
{
Requires.NotNull(projectItem);

if (projectItem.Flags.Contains(DependencyTreeFlags.DependenciesRootNode))
if (projectItem.Flags.Contains(Flags.DependenciesRootNode))
{
menuCommandId = Menus.IDM_VS_CTXT_REFERENCEROOT;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.TargetNode))
else if (projectItem.Flags.Contains(Flags.TargetNode))
{
menuCommandId = Menus.IDM_VS_CTXT_DEPENDENCYTARGET;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.AssemblyDependencyGroup))
else if (projectItem.Flags.Contains(Flags.AssemblyDependencyGroup))
{
menuCommandId = Menus.IDM_VS_CTXT_REFERENCE_GROUP;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.AssemblyDependency))
else if (projectItem.Flags.Contains(Flags.AssemblyDependency))
{
menuCommandId = Menus.IDM_VS_CTXT_REFERENCE;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.PackageDependencyGroup))
else if (projectItem.Flags.Contains(Flags.PackageDependencyGroup))
{
menuCommandId = Menus.IDM_VS_CTXT_PACKAGEREFERENCE_GROUP;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.PackageDependency))
else if (projectItem.Flags.Contains(Flags.PackageDependency))
{
menuCommandId = Menus.IDM_VS_CTXT_PACKAGEREFERENCE;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.ComDependencyGroup))
else if (projectItem.Flags.Contains(Flags.ComDependencyGroup))
{
menuCommandId = Menus.IDM_VS_CTXT_COMREFERENCE_GROUP;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.ComDependency))
else if (projectItem.Flags.Contains(Flags.ComDependency))
{
menuCommandId = Menus.IDM_VS_CTXT_COMREFERENCE;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.ProjectDependencyGroup))
else if (projectItem.Flags.Contains(Flags.ProjectDependencyGroup))
{
menuCommandId = Menus.IDM_VS_CTXT_PROJECTREFERENCE_GROUP;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.ProjectDependency))
else if (projectItem.Flags.Contains(Flags.ProjectDependency))
{
menuCommandId = Menus.IDM_VS_CTXT_PROJECTREFERENCE;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.SharedProjectDependency))
else if (projectItem.Flags.Contains(Flags.SharedProjectDependency))
{
menuCommandId = Menus.IDM_VS_CTXT_SHAREDPROJECTREFERENCE;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.AnalyzerDependencyGroup))
else if (projectItem.Flags.Contains(Flags.AnalyzerDependencyGroup))
{
menuCommandId = Menus.IDM_VS_CTXT_ANALYZERREFERENCE_GROUP;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.AnalyzerDependency))
else if (projectItem.Flags.Contains(Flags.AnalyzerDependency))
{
menuCommandId = Menus.IDM_VS_CTXT_ANALYZERREFERENCE;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.FrameworkDependencyGroup))
else if (projectItem.Flags.Contains(Flags.FrameworkDependencyGroup))
{
menuCommandId = Menus.IDM_VS_CTXT_FRAMEWORKREFERENCE_GROUP;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.FrameworkDependency))
else if (projectItem.Flags.Contains(Flags.FrameworkDependency))
{
menuCommandId = Menus.IDM_VS_CTXT_FRAMEWORKREFERENCE;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.SdkDependencyGroup))
else if (projectItem.Flags.Contains(Flags.SdkDependencyGroup))
{
menuCommandId = Menus.IDM_VS_CTXT_SDKREFERENCE_GROUP;
}
else if (projectItem.Flags.Contains(DependencyTreeFlags.SdkDependency))
else if (projectItem.Flags.Contains(Flags.SdkDependency))
{
menuCommandId = Menus.IDM_VS_CTXT_SDKREFERENCE;
}
Expand Down Expand Up @@ -132,9 +134,9 @@ public bool TryGetMixedItemsContextMenu(IEnumerable<IProjectTree> projectItems,

if (!containsProhibited)
{
if (item.Flags.Contains(DependencyTreeFlags.DependencyGroup) ||
item.Flags.Contains(DependencyTreeFlags.TargetNode) ||
item.Flags.Contains(DependencyTreeFlags.DependenciesRootNode))
if (item.Flags.Contains(Flags.DependencyGroup) ||
item.Flags.Contains(Flags.TargetNode) ||
item.Flags.Contains(Flags.DependenciesRootNode))
{
containsProhibited = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

using Flags = Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies.DependencyTreeFlags;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.Commands
{
/// <summary>
Expand Down Expand Up @@ -58,8 +60,8 @@ protected override async Task<bool> TryHandleCommandAsync(IProjectTree node, boo
private static bool CanNavigateTo(IProjectTree node)
{
return node.Flags.ContainsAny(
DependencyTreeFlags.ProjectDependency |
DependencyTreeFlags.SharedProjectDependency);
Flags.ProjectDependency |
Flags.SharedProjectDependency);
}

private async Task NavigateToAsync(IProjectTree node)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using Microsoft.VisualStudio.ProjectSystem.Input;
using Microsoft.VisualStudio.Threading;

using Flags = Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies.DependencyTreeFlags;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.Commands
{
/// <summary>
Expand All @@ -15,7 +17,7 @@ internal sealed class SuppressObjectBrowserForPackageReferenceCommand : Abstract
{
protected override Task<CommandStatusResult> GetCommandStatusAsync(IProjectTree node, bool focused, string? commandText, CommandStatus progressiveStatus)
{
if (node.Flags.Contains(DependencyTreeFlags.PackageDependency))
if (node.Flags.Contains(Flags.PackageDependency))
{
return GetCommandStatusResult.Suppressed;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.VisualStudio.ProjectSystem.Tree.Dependencies;
using Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies;

namespace Microsoft.VisualStudio.ProjectSystem.CopyPaste
{
Expand Down
Loading