public void Implicit() { var properties = ImmutableStringDictionary <string> .EmptyOrdinal.Add("myProp", "myVal"); var model = new PackageDependencyModel( originalItemSpec: "myOriginalItemSpec", version: "", isResolved: true, isImplicit: true, properties: properties, isVisible: true); Assert.Equal(PackageRuleHandler.ProviderTypeString, model.ProviderType); Assert.Equal("myOriginalItemSpec", model.OriginalItemSpec); Assert.Equal("myOriginalItemSpec", model.Id); Assert.Equal("myOriginalItemSpec", model.Caption); Assert.Equal(ResolvedPackageReference.SchemaName, model.SchemaName); Assert.Equal(PackageReference.PrimaryDataSourceItemType, model.SchemaItemType); Assert.True(model.Visible); Assert.True(model.Resolved); Assert.True(model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(KnownMonikers.NuGetNoColorPrivate, model.Icon); Assert.Equal(KnownMonikers.NuGetNoColorPrivate, model.ExpandedIcon); Assert.Equal(KnownMonikers.NuGetNoColorWarning, model.UnresolvedIcon); Assert.Equal(KnownMonikers.NuGetNoColorWarning, model.UnresolvedExpandedIcon); Assert.Equal( DependencyTreeFlags.PackageDependency + DependencyTreeFlags.SupportsFolderBrowse + DependencyTreeFlags.ResolvedDependencyFlags + ProjectTreeFlags.Create("$ID:myOriginalItemSpec") - DependencyTreeFlags.SupportsRemove, model.Flags); }
public void PackageFrameworkAssembliesDependencyNode_Constructor() { // Arrange var defaultFlags = DependencyNode.DependencyFlags.Union( DependencyNode.PreFilledFolderNode); var caption = "Framework Assemblies"; var id = DependencyNodeId.FromString( "file:///[MyProviderType;c:\\MyItemSpec.dll;MyItemType;MyUniqueToken]"); var properties = new Dictionary <string, string>().ToImmutableDictionary(); var myFlags = ProjectTreeFlags.Create("MyFlag"); // Act var node = new PackageFrameworkAssembliesDependencyNode(id, myFlags, properties, resolved: true); // Assert Assert.Equal(KnownMonikers.Library, node.Icon); Assert.Equal(true, node.Resolved); Assert.Equal(caption, node.Caption); Assert.Equal(properties, node.Properties); Assert.Equal(node.Icon, node.ExpandedIcon); Assert.True(node.Flags.Contains(defaultFlags.Union(myFlags))); }
public void Unresolved() { var properties = ImmutableStringDictionary <string> .EmptyOrdinal.Add("myProp", "myVal"); var flag = ProjectTreeFlags.Create("MyCustomFlag"); var model = new AssemblyDependencyModel( "myProvider", "c:\\myPath", "myOriginalItemSpec", flags: flag, resolved: false, isImplicit: false, properties: properties); Assert.Equal("myProvider", model.ProviderType); Assert.Equal("c:\\myPath", model.Path); Assert.Equal("myOriginalItemSpec", model.OriginalItemSpec); Assert.Equal("c:\\myPath", model.Caption); Assert.Equal(AssemblyReference.SchemaName, model.SchemaName); Assert.False(model.Resolved); Assert.False(model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(Dependency.FrameworkAssemblyNodePriority, model.Priority); Assert.Equal(AssemblyReference.PrimaryDataSourceItemType, model.SchemaItemType); Assert.Equal(KnownMonikers.Reference, model.Icon); Assert.Equal(KnownMonikers.Reference, model.ExpandedIcon); Assert.Equal(KnownMonikers.ReferenceWarning, model.UnresolvedIcon); Assert.Equal(KnownMonikers.ReferenceWarning, model.UnresolvedExpandedIcon); Assert.True(model.Flags.Contains(flag)); }
public void Warning() { var properties = ImmutableDictionary <string, string> .Empty.Add("myProp", "myVal"); var flag = ProjectTreeFlags.Create("MyCustomFlag"); var model = new DiagnosticDependencyModel( "myProvider", "myOriginalItemSpec", DiagnosticMessageSeverity.Warning, "nu1002", "myMessage", flags: flag, isVisible: true, properties: properties); Assert.Equal("myProvider", model.ProviderType); Assert.Equal("myOriginalItemSpec", model.Path); Assert.Equal("myOriginalItemSpec", model.OriginalItemSpec); Assert.Equal("myOriginalItemSpec", model.Id); Assert.Equal("NU1002 myMessage", model.Caption); Assert.False(model.TopLevel); Assert.Equal(true, model.Visible); Assert.Equal(null, model.SchemaName); Assert.Equal(false, model.Resolved); Assert.Equal(false, model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(Dependency.DiagnosticsWarningNodePriority, model.Priority); Assert.Equal(null, model.SchemaItemType); Assert.Equal(ManagedImageMonikers.WarningSmall, model.Icon); Assert.Equal(ManagedImageMonikers.WarningSmall, model.ExpandedIcon); Assert.Equal(ManagedImageMonikers.WarningSmall, model.UnresolvedIcon); Assert.Equal(ManagedImageMonikers.WarningSmall, model.UnresolvedExpandedIcon); Assert.True(model.Flags.Contains(DependencyTreeFlags.DiagnosticWarningNodeFlags)); Assert.True(model.Flags.Contains(flag)); }
public void PackageUnknownDependencyNode_Constructor(bool resolved) { // Arrange var defaultFlags = (resolved ? DependencyNode.ResolvedDependencyFlags : DependencyNode.UnresolvedDependencyFlags) .Add(ProjectTreeFlags.Common.ResolvedReference); var caption = "MyCaption"; var id = DependencyNodeId.FromString( "file:///[MyProviderType;c:\\MyItemSpec.dll;MyItemType;MyUniqueToken]"); var properties = new Dictionary <string, string>().ToImmutableDictionary(); var myFlags = ProjectTreeFlags.Create("MyFlag"); // Act var node = new PackageUnknownDependencyNode(id, caption, myFlags, properties, resolved: resolved); // Assert Assert.Equal(KnownMonikers.QuestionMark, node.Icon); Assert.Equal(resolved, node.Resolved); Assert.Equal(caption, node.Caption); Assert.Equal(properties, node.Properties); Assert.Equal(node.Icon, node.ExpandedIcon); Assert.True(node.Flags.Contains(defaultFlags.Union(myFlags))); }
public void Implicit() { var properties = ImmutableStringDictionary <string> .EmptyOrdinal.Add("myProp", "myVal"); var flag = ProjectTreeFlags.Create("MyCustomFlag"); var model = new ComDependencyModel( "myProvider", "c:\\myPath.dll", "myOriginalItemSpec", flags: flag, resolved: true, isImplicit: true, properties: properties); Assert.Equal("myProvider", model.ProviderType); Assert.Equal("c:\\myPath.dll", model.Path); Assert.Equal("myOriginalItemSpec", model.OriginalItemSpec); Assert.Equal("myPath", model.Caption); Assert.Equal(ResolvedCOMReference.SchemaName, model.SchemaName); Assert.True(model.Resolved); Assert.True(model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(Dependency.ComNodePriority, model.Priority); Assert.Equal(ComReference.PrimaryDataSourceItemType, model.SchemaItemType); Assert.Equal(ManagedImageMonikers.ComponentPrivate, model.Icon); Assert.Equal(ManagedImageMonikers.ComponentPrivate, model.ExpandedIcon); Assert.Equal(ManagedImageMonikers.ComponentWarning, model.UnresolvedIcon); Assert.Equal(ManagedImageMonikers.ComponentWarning, model.UnresolvedExpandedIcon); Assert.True(model.Flags.Contains(flag)); }
public void Unresolved() { var properties = ImmutableStringDictionary <string> .EmptyOrdinal.Add("myProp", "myVal"); var model = new PackageDependencyModel( originalItemSpec: "myOriginalItemSpec", version: "myVersion", isResolved: false, isImplicit: false, properties: properties, isVisible: true); Assert.Equal(PackageRuleHandler.ProviderTypeString, model.ProviderType); Assert.Equal("myOriginalItemSpec", model.OriginalItemSpec); Assert.Equal("myOriginalItemSpec", model.Id); Assert.Equal("myOriginalItemSpec (myVersion)", model.Caption); Assert.Equal(PackageReference.SchemaName, model.SchemaName); Assert.Equal(PackageReference.PrimaryDataSourceItemType, model.SchemaItemType); Assert.True(model.Visible); Assert.False(model.Resolved); Assert.False(model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(ManagedImageMonikers.NuGetGrey, model.Icon); Assert.Equal(ManagedImageMonikers.NuGetGrey, model.ExpandedIcon); Assert.Equal(ManagedImageMonikers.NuGetGreyWarning, model.UnresolvedIcon); Assert.Equal(ManagedImageMonikers.NuGetGreyWarning, model.UnresolvedExpandedIcon); Assert.Equal( DependencyTreeFlags.PackageDependency + DependencyTreeFlags.GenericUnresolvedDependencyFlags + ProjectTreeFlags.Create("$ID:myOriginalItemSpec"), model.Flags); }
public void SubTreeRootDependencyModelTest() { var iconSet = new DependencyIconSet( icon: KnownMonikers.AboutBox, expandedIcon: KnownMonikers.AboutBox, unresolvedIcon: KnownMonikers.AbsolutePosition, unresolvedExpandedIcon: KnownMonikers.AbsolutePosition); var flag = ProjectTreeFlags.Create("MyCustomFlag"); var model = new SubTreeRootDependencyModel( "myProvider", "myRoot", iconSet, flags: flag); Assert.Equal("myProvider", model.ProviderType); Assert.Equal("myRoot", model.Path); Assert.Equal("myRoot", model.OriginalItemSpec); Assert.Equal("myRoot", model.Caption); Assert.Same(iconSet, model.IconSet); Assert.Equal(KnownMonikers.AboutBox, model.Icon); Assert.Equal(KnownMonikers.AboutBox, model.ExpandedIcon); Assert.Equal(KnownMonikers.AbsolutePosition, model.UnresolvedIcon); Assert.Equal(KnownMonikers.AbsolutePosition, model.UnresolvedExpandedIcon); Assert.Equal( flag + DependencyTreeFlags.GenericResolvedDependencyFlags + DependencyTreeFlags.DependencyFlags + DependencyTreeFlags.SubTreeRootNode - DependencyTreeFlags.SupportsRuleProperties - DependencyTreeFlags.SupportsRemove, model.Flags); }
public void Implicit() { var properties = ImmutableStringDictionary<string>.EmptyOrdinal.Add("myProp", "myVal"); var model = new ProjectDependencyModel( "c:\\ResolvedPath\\MyProject.dll", "Project\\MyProject.csproj", isResolved: true, isImplicit: true, properties: properties); Assert.Equal(ProjectRuleHandler.ProviderTypeString, model.ProviderType); Assert.Equal("c:\\ResolvedPath\\MyProject.dll", model.Path); Assert.Equal("Project\\MyProject.csproj", model.OriginalItemSpec); Assert.Equal("MyProject", model.Caption); Assert.Equal(ResolvedProjectReference.SchemaName, model.SchemaName); Assert.True(model.Resolved); Assert.True(model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(ProjectReference.PrimaryDataSourceItemType, model.SchemaItemType); Assert.Equal(KnownMonikers.ApplicationPrivate, model.Icon); Assert.Equal(KnownMonikers.ApplicationPrivate, model.ExpandedIcon); Assert.Equal(KnownMonikers.ApplicationWarning, model.UnresolvedIcon); Assert.Equal(KnownMonikers.ApplicationWarning, model.UnresolvedExpandedIcon); Assert.Equal( DependencyTreeFlags.ProjectDependency + DependencyTreeFlags.SupportsBrowse + DependencyTreeFlags.GenericResolvedDependencyFlags - DependencyTreeFlags.SupportsRemove + ProjectTreeFlags.Create("$ID:MyProject"), model.Flags); }
protected override bool TryGetProjectNode(IProjectTree targetRootNode, IRelatableItem item, [NotNullWhen(returnValue: true)] out IProjectTree?projectTree) { IProjectTree?typeGroupNode = targetRootNode.FindChildWithFlags(DependencyTreeFlags.ProjectDependencyGroup); projectTree = typeGroupNode?.FindChildWithFlags(ProjectTreeFlags.Create("$ID:" + Library.Name)); return(projectTree != null); }
public void CalculatePropertyValues(IProjectTreeCustomizablePropertyContext propertyContext, IProjectTreeCustomizablePropertyValues propertyValues) { // Package content items always come in as linked items, so to reduce // the number of items we look at, we limit ourselves to them if (propertyValues.Flags.Contains(ProjectTreeFlags.LinkedItem) && propertyContext.Metadata != null && propertyContext.Metadata.TryGetValue(None.NuGetPackageIdProperty, out string packageId) && packageId.Length > 0) { // TODO: Replace this with strongly typed value when we next update propertyValues.Flags |= ProjectTreeFlags.Create("UserReadOnly"); } }
/// <summary> /// Updates the shared project import nodes that are shown under the 'Dependencies/Projects' node. /// </summary> /// <param name="sharedFolders">Snapshot of shared folders.</param> /// <param name="dependenciesChange"></param> /// <returns></returns> protected override void ProcessSharedProjectImportNodes(IProjectSharedFoldersSnapshot sharedFolders, DependenciesChange dependenciesChange) { Requires.NotNull(sharedFolders, nameof(sharedFolders)); Requires.NotNull(dependenciesChange, nameof(dependenciesChange)); var sharedFolderProjectPaths = sharedFolders.Value.Select(sf => sf.ProjectPath); var rootNodeChildren = RootNode.Children; var currentSharedImportNodes = rootNodeChildren .Where(x => x.Flags.Contains(ProjectTreeFlags.Common.SharedProjectImportReference)); var currentSharedImportNodePaths = currentSharedImportNodes.Select(x => x.Id.ItemSpec); // process added nodes IEnumerable <string> addedSharedImportPaths = sharedFolderProjectPaths.Except(currentSharedImportNodePaths); var itemType = ResolvedProjectReference.PrimaryDataSourceItemType; foreach (string addedSharedImportPath in addedSharedImportPaths) { rootNodeChildren = RootNode.Children; var node = rootNodeChildren.FindNode(addedSharedImportPath, itemType); if (node == null) { var sharedFlags = ProjectTreeFlags.Create(ProjectTreeFlags.Common.SharedProjectImportReference); var id = new DependencyNodeId(ProviderType, addedSharedImportPath, itemType); node = new SharedProjectDependencyNode(id, flags: sharedFlags); dependenciesChange.AddedNodes.Add(node); } } // process removed nodes var removedSharedImportPaths = currentSharedImportNodePaths.Except(sharedFolderProjectPaths); foreach (string removedSharedImportPath in removedSharedImportPaths) { var existingImportNode = currentSharedImportNodes .Where(node => PathHelper.IsSamePath(node.Id.ItemSpec, removedSharedImportPath)) .FirstOrDefault(); if (existingImportNode != null) { dependenciesChange.RemovedNodes.Add(existingImportNode); } } }
public void Unresolved() { var properties = ImmutableDictionary <string, string> .Empty.Add("myProp", "myVal"); var dependencyIDs = new[] { "id1", "id2" }; var flag = ProjectTreeFlags.Create("MyCustomFlag"); var model = new PackageDependencyModel( providerType: "myProvider", path: "c:\\myPath", originalItemSpec: "myOriginalItemSpec", name: "myPath", flags: flag, version: "myVersion", resolved: false, isImplicit: false, properties: properties, isTopLevel: true, isVisible: true, dependenciesIDs: dependencyIDs); Assert.Equal("myProvider", model.ProviderType); Assert.Equal("c:\\myPath", model.Path); Assert.Equal("myPath", model.Name); Assert.Equal("myOriginalItemSpec", model.OriginalItemSpec); Assert.Equal("myOriginalItemSpec", model.Id); Assert.Equal("myVersion", model.Version); Assert.Equal("myPath (myVersion)", model.Caption); Assert.Equal(PackageReference.SchemaName, model.SchemaName); Assert.Equal(PackageReference.PrimaryDataSourceItemType, model.SchemaItemType); Assert.True(model.TopLevel); Assert.True(model.Visible); Assert.False(model.Resolved); Assert.False(model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(Dependency.UnresolvedReferenceNodePriority, model.Priority); Assert.Equal(ManagedImageMonikers.NuGetGrey, model.Icon); Assert.Equal(ManagedImageMonikers.NuGetGrey, model.ExpandedIcon); Assert.Equal(ManagedImageMonikers.NuGetGreyWarning, model.UnresolvedIcon); Assert.Equal(ManagedImageMonikers.NuGetGreyWarning, model.UnresolvedExpandedIcon); AssertEx.CollectionLength(model.DependencyIDs, 2); Assert.True(model.Flags.Contains(DependencyTreeFlags.PackageNodeFlags)); Assert.True(model.Flags.Contains(DependencyTreeFlags.SupportsHierarchy)); Assert.True(model.Flags.Contains(flag)); }
public void DependencyNode_Constructor_FlagsAndResolved(bool resolved) { // Arrange var id = DependencyNodeId.FromString( "file:///[MyProviderType;MyItemSpec;MyItemType;MyUniqueToken]"); var myFlags = ProjectTreeFlags.Create("CustomFlag"); // Act var node = new DependencyNode(id, myFlags, resolved: resolved); // Assert var expectedFlags = resolved ? DependencyNode.GenericResolvedDependencyFlags.Union(myFlags) : DependencyNode.GenericUnresolvedDependencyFlags.Union(myFlags); Assert.True(node.Flags.Contains(expectedFlags)); Assert.Equal(resolved, node.Resolved); }
public void PackageDependencyNode_Constructor(bool resolved) { // Arrange var expectedIcon = resolved ? KnownMonikers.PackageReference : KnownMonikers.ReferenceWarning; var defaultFlags = (resolved ? DependencyNode.GenericResolvedDependencyFlags : DependencyNode.GenericUnresolvedDependencyFlags); var priority = resolved ? DependencyNode.PackageNodePriority : DependencyNode.UnresolvedReferenceNodePriority; var name = "MyName"; var caption = "MyCaption (xxx)"; var id = DependencyNodeId.FromString( "file:///[MyProviderType;c:\\MyItemSpec.dll;MyItemType;MyUniqueToken]"); var properties = new Dictionary <string, string>().ToImmutableDictionary(); var myFlags = ProjectTreeFlags.Create("MyFlag"); // Act var node = new PackageDependencyNode(id, name, caption, myFlags, properties, resolved: resolved); // Assert Assert.Equal(expectedIcon, node.Icon); Assert.Equal(resolved, node.Resolved); Assert.Equal(priority, node.Priority); Assert.Equal(name, node.Name); Assert.Equal(caption, node.Caption); Assert.Equal(node.Alias, node.Caption); Assert.Equal(properties, node.Properties); Assert.Equal(node.Icon, node.ExpandedIcon); Assert.True(node.Flags.Contains(defaultFlags.Union(myFlags))); }
public async Task <IDependenciesTreeConfiguredProjectSearchContext?> ForConfiguredProjectAsync(ConfiguredProject configuredProject, CancellationToken cancellationToken = default) { Requires.NotNull(configuredProject, nameof(configuredProject)); IProjectTree targetRootNode; if (_dependenciesNode.FindChildWithFlags(DependencyTreeFlags.TargetNode) == null) { // Tree does not show any target nodes targetRootNode = _dependenciesNode; } else { if (configuredProject.Services.ProjectSubscription == null) { return(null); } IProjectSubscriptionUpdate subscriptionUpdate = (await configuredProject.Services.ProjectSubscription.ProjectRuleSource.GetLatestVersionAsync(configuredProject, cancellationToken: cancellationToken)).Value; if (!subscriptionUpdate.CurrentState.TryGetValue(ConfigurationGeneral.SchemaName, out IProjectRuleSnapshot configurationGeneralSnapshot) || !configurationGeneralSnapshot.Properties.TryGetValue(ConfigurationGeneral.TargetFrameworkProperty, out string tf)) { return(null); } IProjectTree?targetNode = _dependenciesNode.FindChildWithFlags(ProjectTreeFlags.Create("$TFM:" + tf)); if (targetNode == null) { TraceUtilities.TraceError("Should not fail to find the target node."); return(null); } targetRootNode = targetNode; } return(new DependenciesTreeConfiguredProjectSearchContext(_inner, targetRootNode, _hierarchyItemManager, _projectVsServices, _relationProvider)); }
public void Unresolved() { var properties = ImmutableStringDictionary <string> .EmptyOrdinal.Add("myProp", "myVal"); var dependencyIDs = new[] { "id1", "id2" }; var flag = ProjectTreeFlags.Create("MyCustomFlag"); var model = new PackageAnalyzerAssemblyDependencyModel( providerType: "myProvider", path: "c:\\myPath", originalItemSpec: "myOriginalItemSpec", name: "myPath", flags: flag, resolved: false, properties: properties, dependenciesIDs: dependencyIDs); Assert.Equal("myProvider", model.ProviderType); Assert.Equal("c:\\myPath", model.Path); Assert.Equal("myPath", model.Name); Assert.Equal("myOriginalItemSpec", model.OriginalItemSpec); Assert.Equal("myPath", model.Caption); Assert.Null(model.SchemaName); Assert.False(model.TopLevel); Assert.True(model.Visible); Assert.False(model.Resolved); Assert.False(model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(Dependency.UnresolvedReferenceNodePriority, model.Priority); Assert.Equal(KnownMonikers.CodeInformation, model.Icon); Assert.Equal(KnownMonikers.CodeInformation, model.ExpandedIcon); Assert.Equal(ManagedImageMonikers.CodeInformationWarning, model.UnresolvedIcon); Assert.Equal(ManagedImageMonikers.CodeInformationWarning, model.UnresolvedExpandedIcon); AssertEx.CollectionLength(model.DependencyIDs, 2); Assert.True(model.Flags.Contains(flag)); }
public void Resolved() { var properties = ImmutableDictionary <string, string> .Empty.Add("myProp", "myVal"); var dependencyIDs = new[] { "id1", "id2" }; var flag = ProjectTreeFlags.Create("MyCustomFlag"); var model = new PackageUnknownDependencyModel( providerType: "myProvider", path: "c:\\myPath", originalItemSpec: "myOriginalItemSpec", name: "myPath", flags: flag, resolved: true, properties: properties, dependenciesIDs: dependencyIDs); Assert.Equal("myProvider", model.ProviderType); Assert.Equal("c:\\myPath", model.Path); Assert.Equal("myPath", model.Name); Assert.Equal("myOriginalItemSpec", model.OriginalItemSpec); Assert.Equal("myPath", model.Caption); Assert.Equal(null, model.SchemaName); Assert.Equal(false, model.TopLevel); Assert.Equal(true, model.Visible); Assert.Equal(true, model.Resolved); Assert.Equal(false, model.Implicit); Assert.Equal(properties, model.Properties); Assert.Equal(Dependency.UnresolvedReferenceNodePriority, model.Priority); Assert.Equal(KnownMonikers.QuestionMark, model.Icon); Assert.Equal(KnownMonikers.QuestionMark, model.ExpandedIcon); Assert.Equal(KnownMonikers.QuestionMark, model.UnresolvedIcon); Assert.Equal(KnownMonikers.QuestionMark, model.UnresolvedExpandedIcon); Assert.Equal(2, model.DependencyIDs.Count); Assert.True(model.Flags.Contains(flag)); }
public async Task WhenMultipleTargetSnapshotsWithExistingDependencies_ShouldApplyChanges() { var dependencyModelRootXxx = new TestDependencyModel { ProviderType = "Xxx", Id = "XxxDependencyRoot", OriginalItemSpec = "XxxDependencyRoot", Caption = "XxxDependencyRoot", Resolved = true }; var dependencyXxx1 = new TestDependency { ProviderType = "Xxx", Id = "dependency1", FilePath = "dependencyxxxpath", OriginalItemSpec = "dependency1", Caption = "Dependency1", SchemaItemType = "Xxx", Resolved = true }; var dependencyModelRootYyy = new TestDependencyModel { ProviderType = "Yyy", Id = "YyyDependencyRoot", OriginalItemSpec = "YyyDependencyRoot", Caption = "YyyDependencyRoot" }; var dependencyYyy1 = new TestDependency { ProviderType = "Yyy", Id = "dependency1", FilePath = "dependencyyyypath", OriginalItemSpec = "dependency1", Caption = "Dependency1", SchemaItemType = "Yyy", Resolved = true }; var dependencyYyyExisting = new TestDependency { ProviderType = "Yyy", Id = "dependencyExisting", FilePath = "dependencyyyyExistingpath", OriginalItemSpec = "dependencyExisting", Caption = "DependencyExisting", SchemaItemType = "Yyy", Resolved = true }; var dependencyModelRootZzz = new TestDependencyModel { ProviderType = "Zzz", Id = "ZzzDependencyRoot", OriginalItemSpec = "ZzzDependencyRoot", Caption = "ZzzDependencyRoot", Resolved = true, Flags = ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp) }; var dependencyAny1 = new TestDependency { ProviderType = "Zzz", Id = "ZzzDependencyAny1", FilePath = "ZzzDependencyAny1path", OriginalItemSpec = "ZzzDependencyAny1", Caption = "ZzzDependencyAny1" }; var dependenciesRoot = new TestProjectTree { Caption = "MyDependencies", Children = { new TestProjectTree { Caption = "OldRootChildToBeRemoved" }, new TestProjectTree { Caption = "YyyDependencyRoot", Children = { new TestProjectTree { Caption = "DependencyExisting", } } } } }; var targetModel1 = new TestDependencyModel { Id = "tfm1", OriginalItemSpec = "tfm1", Caption = "tfm1" }; var targetModel2 = new TestDependencyModel { Id = "tfm2", OriginalItemSpec = "tfm2", Caption = "tfm2" }; var provider = CreateProvider( rootModels: new[] { dependencyModelRootXxx, dependencyModelRootYyy, dependencyModelRootZzz }, targetModels: new[] { targetModel1, targetModel2 }); var snapshot = GetSnapshot( (_tfm1, new[] { dependencyXxx1, dependencyYyy1, dependencyYyyExisting }), (_tfm2, new[] { dependencyXxx1, dependencyYyy1, dependencyYyyExisting }), (TargetFramework.Any, new[] { dependencyAny1 })); // Act var resultTree = await provider.BuildTreeAsync(dependenciesRoot, snapshot); // Assert const string expectedFlatHierarchy = @"Caption=MyDependencies, IconHash=325248080, ExpandedIconHash=325248080, Rule=, IsProjectItem=False, CustomTag= Caption=ZzzDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=ZzzDependencyAny1, IconHash=325248665, ExpandedIconHash=325248817, Rule=, IsProjectItem=False, CustomTag= Caption=tfm2, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag=, BubbleUpFlag=True Caption=XxxDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, IconHash=325248088, ExpandedIconHash=325248260, Rule=, IsProjectItem=False, CustomTag= Caption=YyyDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, IconHash=325248088, ExpandedIconHash=325248260, Rule=, IsProjectItem=False, CustomTag= Caption=DependencyExisting, IconHash=325248088, ExpandedIconHash=325248260, Rule=, IsProjectItem=False, CustomTag= Caption=tfm1, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag=, BubbleUpFlag=True Caption=XxxDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, IconHash=325248088, ExpandedIconHash=325248260, Rule=, IsProjectItem=True, CustomTag= Caption=YyyDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, IconHash=325248088, ExpandedIconHash=325248260, Rule=, IsProjectItem=True, CustomTag= Caption=DependencyExisting, IconHash=325248088, ExpandedIconHash=325248260, Rule=, IsProjectItem=True, CustomTag="; AssertTestData(expectedFlatHierarchy, resultTree); }
public async Task <IProjectTree> BuildTreeAsync( IProjectTree dependenciesTree, DependenciesSnapshot snapshot, CancellationToken cancellationToken = default) { // Keep a reference to the original tree to return in case we are cancelled. IProjectTree originalTree = dependenciesTree; bool hasSingleTarget = snapshot.DependenciesByTargetFramework.Count(x => !x.Key.Equals(TargetFramework.Any)) == 1; var currentTopLevelNodes = new HashSet <IProjectTree>(); if (hasSingleTarget) { await BuildSingleTargetTreeAsync(); } else { await BuildMultiTargetTreeAsync(); } if (cancellationToken.IsCancellationRequested) { return(originalTree); } dependenciesTree = CleanupOldNodes(dependenciesTree, currentTopLevelNodes); ProjectImageMoniker rootIcon = _viewModelFactory.GetDependenciesRootIcon(snapshot.HasReachableVisibleUnresolvedDependency).ToProjectSystemType(); return(dependenciesTree.SetProperties(icon: rootIcon, expandedIcon: rootIcon)); async Task BuildSingleTargetTreeAsync() { foreach ((ITargetFramework _, TargetedDependenciesSnapshot targetedSnapshot) in snapshot.DependenciesByTargetFramework) { if (cancellationToken.IsCancellationRequested) { return; } dependenciesTree = await BuildSubTreesAsync( rootNode : dependenciesTree, snapshot.ActiveTargetFramework, targetedSnapshot, RememberNewNodes); } } async Task BuildMultiTargetTreeAsync() { foreach ((ITargetFramework targetFramework, TargetedDependenciesSnapshot targetedSnapshot) in snapshot.DependenciesByTargetFramework) { if (cancellationToken.IsCancellationRequested) { return; } if (targetFramework.Equals(TargetFramework.Any)) { dependenciesTree = await BuildSubTreesAsync( rootNode : dependenciesTree, snapshot.ActiveTargetFramework, targetedSnapshot, RememberNewNodes); } else { IProjectTree? node = dependenciesTree.FindChildWithCaption(targetFramework.FriendlyName); bool shouldAddTargetNode = node == null; IDependencyViewModel targetViewModel = _viewModelFactory.CreateTargetViewModel(targetedSnapshot); node = CreateOrUpdateNode( node, targetViewModel, browseObjectProperties: null, isProjectItem: false, additionalFlags: ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp)); node = await BuildSubTreesAsync( rootNode : node, snapshot.ActiveTargetFramework, targetedSnapshot, CleanupOldNodes); dependenciesTree = shouldAddTargetNode ? dependenciesTree.Add(node).Parent ! : node.Parent !; Assumes.NotNull(dependenciesTree); currentTopLevelNodes.Add(node); } } } IProjectTree RememberNewNodes(IProjectTree rootNode, IEnumerable <IProjectTree> currentNodes) { if (currentNodes != null) { currentTopLevelNodes.AddRange(currentNodes); } return(rootNode); } }
/// <summary> /// Builds all available sub trees under root: target framework or Dependencies node /// when there is only one target. /// </summary> private async Task <IProjectTree> BuildSubTreesAsync( IProjectTree rootNode, ITargetFramework activeTarget, TargetedDependenciesSnapshot targetedSnapshot, Func <IProjectTree, HashSet <IProjectTree>, IProjectTree> syncFunc) { var groupedByProviderType = new Dictionary <string, List <IDependency> >(StringComparers.DependencyProviderTypes); foreach (IDependency dependency in targetedSnapshot.TopLevelDependencies) { if (!dependency.Visible) { // If a dependency is not visible we will still register a top-level group if it // has the ShowEmptyProviderRootNode flag. if (!dependency.Flags.Contains(DependencyTreeFlags.ShowEmptyProviderRootNode)) { // No such flag, so skip it completely. continue; } } if (!groupedByProviderType.TryGetValue(dependency.ProviderType, out List <IDependency> dependencies)) { dependencies = new List <IDependency>(); groupedByProviderType.Add(dependency.ProviderType, dependencies); } // Only add visible dependencies. See note above. if (dependency.Visible) { dependencies.Add(dependency); } } var currentNodes = new HashSet <IProjectTree>(capacity: groupedByProviderType.Count); bool isActiveTarget = targetedSnapshot.TargetFramework.Equals(activeTarget); foreach ((string providerType, List <IDependency> dependencies) in groupedByProviderType) { IDependencyViewModel?subTreeViewModel = _viewModelFactory.CreateRootViewModel( providerType, targetedSnapshot.CheckForUnresolvedDependencies(providerType)); if (subTreeViewModel == null) { // In theory this should never happen, as it means we have a dependency model of a type // that no provider claims. https://github.com/dotnet/project-system/issues/3653 continue; } IProjectTree?subTreeNode = rootNode.FindChildWithCaption(subTreeViewModel.Caption); bool isNewSubTreeNode = subTreeNode == null; ProjectTreeFlags excludedFlags = targetedSnapshot.TargetFramework.Equals(TargetFramework.Any) ? ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp) : ProjectTreeFlags.Empty; subTreeNode = CreateOrUpdateNode( subTreeNode, subTreeViewModel, browseObjectProperties: null, isProjectItem: false, excludedFlags: excludedFlags); subTreeNode = await BuildSubTreeAsync( subTreeNode, targetedSnapshot, dependencies, isActiveTarget, shouldCleanup : !isNewSubTreeNode); currentNodes.Add(subTreeNode); rootNode = isNewSubTreeNode ? rootNode.Add(subTreeNode).Parent ! : subTreeNode.Parent !; Assumes.NotNull(rootNode); } return(syncFunc(rootNode, currentNodes)); }
/// <summary> /// Generates the original references directory tree. /// </summary> protected override void Initialize() { #pragma warning disable RS0030 // symbol LoadedProject is banned using (UnconfiguredProjectAsynchronousTasksService.LoadedProject()) #pragma warning restore RS0030 { #pragma warning disable RS0030 // https://github.com/dotnet/roslyn-analyzers/issues/3295 base.Initialize(); #pragma warning restore RS0030 // this.IsApplicable may take a project lock, so we can't do it inline with this method // which is holding a private lock. It turns out that doing it asynchronously isn't a problem anyway, // so long as we guard against races with the Dispose method. #pragma warning disable RS0030 // symbol LoadedProjectAsync is banned UnconfiguredProjectAsynchronousTasksService.LoadedProjectAsync( #pragma warning restore RS0030 async delegate { await TaskScheduler.Default.SwitchTo(alwaysYield: true); UnconfiguredProjectAsynchronousTasksService .UnloadCancellationToken.ThrowIfCancellationRequested(); lock (SyncObject) { Verify.NotDisposed(this); // Issue this token before hooking the SnapshotChanged event to prevent a race // where a snapshot tree is replaced by the initial, empty tree created below. // The handler will cancel this token before submitting its update. CancellationToken initialTreeCancellationToken = _treeUpdateCancellationSeries.CreateNext(); _ = SubmitTreeUpdateAsync( delegate { IProjectTree dependenciesNode = CreateDependenciesNode(); return(Task.FromResult(new TreeUpdateResult(dependenciesNode))); }, initialTreeCancellationToken); ITargetBlock <SnapshotChangedEventArgs> actionBlock = DataflowBlockFactory.CreateActionBlock <SnapshotChangedEventArgs>( OnDependenciesSnapshotChangedAsync, _project, nameFormat: "DependenciesProjectTreeProviderSource {1}", skipIntermediateInputData: true); _snapshotEventListener = _dependenciesSnapshotProvider.SnapshotChangedSource.LinkTo(actionBlock, DataflowOption.PropagateCompletion); } }, registerFaultHandler: true); } IProjectTree CreateDependenciesNode() { var values = new ReferencesProjectTreeCustomizablePropertyValues { Caption = Resources.DependenciesNodeName, Icon = KnownMonikers.ReferenceGroup.ToProjectSystemType(), ExpandedIcon = KnownMonikers.ReferenceGroup.ToProjectSystemType(), Flags = ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp) + ProjectTreeFlags.Create(ProjectTreeFlags.Common.ReferencesFolder) + ProjectTreeFlags.Create(ProjectTreeFlags.Common.VirtualFolder) + DependencyTreeFlags.DependenciesRootNode }; // Allow property providers to perform customization. // These are ordered from lowest priority to highest, allowing higher priority // providers to override lower priority providers. foreach (IProjectTreePropertiesProvider provider in _projectTreePropertiesProviders.ExtensionValues()) { provider.CalculatePropertyValues(ProjectTreeCustomizablePropertyContext.Instance, values); } return(NewTree( caption: values.Caption, icon: values.Icon, expandedIcon: values.ExpandedIcon, flags: values.Flags)); } }
/// <summary> /// Builds Dependencies tree for given dependencies snapshot /// </summary> public override async Task <IProjectTree> BuildTreeAsync( IProjectTree dependenciesTree, IDependenciesSnapshot snapshot, CancellationToken cancellationToken = default) { IProjectTree originalTree = dependenciesTree; var currentTopLevelNodes = new List <IProjectTree>(); IProjectTree RememberNewNodes(IProjectTree rootNode, IEnumerable <IProjectTree> currentNodes) { if (currentNodes != null) { currentTopLevelNodes.AddRange(currentNodes); } return(rootNode); } if (snapshot.Targets.Count(x => !x.Key.Equals(TargetFramework.Any)) == 1) { foreach ((ITargetFramework _, ITargetedDependenciesSnapshot targetedSnapshot) in snapshot.Targets) { if (cancellationToken.IsCancellationRequested) { return(originalTree); } dependenciesTree = await BuildSubTreesAsync( rootNode : dependenciesTree, snapshot.ActiveTarget, targetedSnapshot, RememberNewNodes); } } else { foreach ((ITargetFramework targetFramework, ITargetedDependenciesSnapshot targetedSnapshot) in snapshot.Targets) { if (cancellationToken.IsCancellationRequested) { return(originalTree); } if (targetFramework.Equals(TargetFramework.Any)) { dependenciesTree = await BuildSubTreesAsync( rootNode : dependenciesTree, snapshot.ActiveTarget, targetedSnapshot, RememberNewNodes); } else { IProjectTree node = dependenciesTree.FindChildWithCaption(targetFramework.FriendlyName); bool shouldAddTargetNode = node == null; IDependencyViewModel targetViewModel = ViewModelFactory.CreateTargetViewModel(targetedSnapshot); node = CreateOrUpdateNode( node, targetViewModel, rule: null, isProjectItem: false, additionalFlags: ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp)); node = await BuildSubTreesAsync( rootNode : node, snapshot.ActiveTarget, targetedSnapshot, CleanupOldNodes); dependenciesTree = shouldAddTargetNode ? dependenciesTree.Add(node).Parent : node.Parent; currentTopLevelNodes.Add(node); } } } dependenciesTree = CleanupOldNodes(dependenciesTree, currentTopLevelNodes); // now update root Dependencies node status ProjectImageMoniker rootIcon = ViewModelFactory.GetDependenciesRootIcon(snapshot.HasUnresolvedDependency).ToProjectSystemType(); return(dependenciesTree.SetProperties(icon: rootIcon, expandedIcon: rootIcon)); }
/// <summary> /// Builds all available sub trees under root: target framework or Dependencies node /// when there is only one target. /// </summary> private async Task <IProjectTree> BuildSubTreesAsync( IProjectTree rootNode, ITargetFramework activeTarget, ITargetedDependenciesSnapshot targetedSnapshot, Func <IProjectTree, IEnumerable <IProjectTree>, IProjectTree> syncFunc) { var groupedByProviderType = new Dictionary <string, List <IDependency> >(StringComparers.DependencyProviderTypes); foreach (IDependency dependency in targetedSnapshot.TopLevelDependencies) { if (!dependency.Visible) { if (dependency.Flags.Contains(DependencyTreeFlags.ShowEmptyProviderRootNode)) { // if provider sends special invisible node with flag ShowEmptyProviderRootNode, we // need to show provider node even if it does not have any dependencies. groupedByProviderType.Add(dependency.ProviderType, new List <IDependency>()); } continue; } if (!groupedByProviderType.TryGetValue(dependency.ProviderType, out List <IDependency> dependencies)) { dependencies = new List <IDependency>(); groupedByProviderType.Add(dependency.ProviderType, dependencies); } dependencies.Add(dependency); } var currentNodes = new List <IProjectTree>(capacity: groupedByProviderType.Count); bool isActiveTarget = targetedSnapshot.TargetFramework.Equals(activeTarget); foreach ((string providerType, List <IDependency> dependencies) in groupedByProviderType) { IDependencyViewModel subTreeViewModel = ViewModelFactory.CreateRootViewModel( providerType, targetedSnapshot.CheckForUnresolvedDependencies(providerType)); IProjectTree subTreeNode = rootNode.FindChildWithCaption(subTreeViewModel.Caption); bool isNewSubTreeNode = subTreeNode == null; ProjectTreeFlags excludedFlags = targetedSnapshot.TargetFramework.Equals(TargetFramework.Any) ? ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp) : ProjectTreeFlags.Empty; subTreeNode = CreateOrUpdateNode( subTreeNode, subTreeViewModel, rule: null, isProjectItem: false, excludedFlags: excludedFlags); subTreeNode = await BuildSubTreeAsync( subTreeNode, targetedSnapshot, dependencies, isActiveTarget, shouldCleanup : !isNewSubTreeNode); currentNodes.Add(subTreeNode); rootNode = isNewSubTreeNode ? rootNode.Add(subTreeNode).Parent : subTreeNode.Parent; } return(syncFunc(rootNode, currentNodes)); }
public void Matches_SingleFlag_CaseInsensitive(string s, bool expected) { var detector = new FlagsStringMatcher(ProjectTreeFlags.Create("APPLE"), RegexOptions.IgnoreCase); Assert.Equal(expected, detector.Matches(s)); }
public void GrouppedByTargetTreeViewProvider_WhenMultipleTargetSnapshotsWithExistingDependencies_ShouldApplyChanges() { var tfm1 = ITargetFrameworkFactory.Implement(moniker: "tfm1"); var tfm2 = ITargetFrameworkFactory.Implement(moniker: "tfm2"); var tfmAny = ITargetFrameworkFactory.Implement(moniker: "any"); var dependencyRootXxx = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Xxx"", ""Id"": ""XxxDependencyRoot"", ""Name"":""XxxDependencyRoot"", ""Caption"":""XxxDependencyRoot"", ""Resolved"":""true"" }"); var dependencyXxx1 = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Xxx"", ""Id"": ""xxx\\dependency1"", ""Path"": ""dependencyxxxpath"", ""Name"":""dependency1"", ""Caption"":""Dependency1"", ""SchemaItemType"":""Xxx"", ""Resolved"":""true"" }", icon: KnownMonikers.Uninstall, expandedIcon: KnownMonikers.Uninstall, targetFramework: tfm1); var dependencyRootYyy = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Yyy"", ""Id"": ""YyyDependencyRoot"", ""Name"":""YyyDependencyRoot"", ""Caption"":""YyyDependencyRoot"" }"); var dependencyYyy1 = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Yyy"", ""Id"": ""yyy\\dependency1"", ""Path"": ""dependencyyyypath"", ""Name"":""dependency1"", ""Caption"":""Dependency1"", ""SchemaItemType"":""Yyy"", ""Resolved"":""true"" }", icon: KnownMonikers.Uninstall, expandedIcon: KnownMonikers.Uninstall, targetFramework: tfm1); var dependencyYyyExisting = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Yyy"", ""Id"": ""yyy\\dependencyExisting"", ""Path"": ""dependencyyyyExistingpath"", ""Name"":""dependencyExisting"", ""Caption"":""DependencyExisting"", ""SchemaItemType"":""Yyy"", ""Resolved"":""true"" }", icon: KnownMonikers.Uninstall, expandedIcon: KnownMonikers.Uninstall, targetFramework: tfm1); var dependencyRootZzz = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Zzz"", ""Id"": ""ZzzDependencyRoot"", ""Name"":""ZzzDependencyRoot"", ""Caption"":""ZzzDependencyRoot"", ""Resolved"":""true"" }", flags: ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp)); var dependencyAny1 = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Zzz"", ""Id"": ""ZzzDependencyAny1"", ""Path"": ""ZzzDependencyAny1path"", ""Name"":""ZzzDependencyAny1"", ""Caption"":""ZzzDependencyAny1"" }", targetFramework: tfmAny); var dependencies = new List <IDependency> { dependencyXxx1, dependencyYyy1, dependencyYyyExisting }; var dependenciesAny = new List <IDependency> { dependencyAny1 }; var oldRootChildToBeRemoved = new TestProjectTree { Caption = "OldRootChildToBeRemoved", FilePath = "" }; var dependencyYyyExistingTree = new TestProjectTree { Caption = "DependencyExisting", FilePath = "yyy\\dependencyExisting" }; var dependencyRootYyyTree = new TestProjectTree { Caption = "YyyDependencyRoot", FilePath = "YyyDependencyRoot" }; dependencyRootYyyTree.Add(dependencyYyyExistingTree); var dependenciesRoot = new TestProjectTree { Caption = "MyDependencies", FilePath = "" }; dependenciesRoot.Add(oldRootChildToBeRemoved); dependenciesRoot.Add(dependencyRootYyyTree); var target1 = IDependencyFactory.FromJson(@" { ""Id"": ""tfm1"", ""Name"":""tfm1"", ""Caption"":""tfm1"" }"); var target2 = IDependencyFactory.FromJson(@" { ""Id"": ""tfm2"", ""Name"":""tfm2"", ""Caption"":""tfm2"" }"); var targetAny = IDependencyFactory.FromJson(@" { ""Id"": ""any"", ""Name"":""any"", ""Caption"":""any"" }"); var treeViewModelFactory = IMockDependenciesViewModelFactory.Implement( getDependenciesRootIcon: KnownMonikers.AboutBox, createRootViewModel: new[] { dependencyRootXxx, dependencyRootYyy, dependencyRootZzz }, createTargetViewModel: new[] { target1, target2 }); var testData = new Dictionary <ITargetFramework, List <IDependency> > { { tfm1, dependencies }, { tfm2, dependencies }, { tfmAny, dependenciesAny } }; var project = UnconfiguredProjectFactory.Create(filePath: @"c:\somefodler\someproject.csproj"); var commonServices = IUnconfiguredProjectCommonServicesFactory.Create(project: project); var provider = new GroupedByTargetTreeViewProvider( new MockIDependenciesTreeServices(), treeViewModelFactory, commonServices); // Act var resultTree = provider.BuildTree(dependenciesRoot, GetSnapshot(testData)); // Assert var expectedFlatHierarchy = @"Caption=MyDependencies, FilePath=, IconHash=325248080, ExpandedIconHash=325248080, Rule=, IsProjectItem=False, CustomTag= Caption=tfm2, FilePath=tfm2, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag=, BubbleUpFlag=True Caption=YyyDependencyRoot, FilePath=YyyDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, FilePath=tfm1\Yyy\dependencyyyypath, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=False, CustomTag= Caption=DependencyExisting, FilePath=tfm1\Yyy\dependencyyyyExistingpath, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=False, CustomTag= Caption=XxxDependencyRoot, FilePath=XxxDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, FilePath=tfm1\Xxx\dependencyxxxpath, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=False, CustomTag= Caption=ZzzDependencyRoot, FilePath=ZzzDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=ZzzDependencyAny1, FilePath=ZzzDependencyAny1, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=tfm1, FilePath=tfm1, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag=, BubbleUpFlag=True Caption=YyyDependencyRoot, FilePath=YyyDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, FilePath=tfm1\Yyy\dependencyyyypath, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=True, CustomTag= Caption=DependencyExisting, FilePath=tfm1\Yyy\dependencyyyyExistingpath, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=True, CustomTag= Caption=XxxDependencyRoot, FilePath=XxxDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, FilePath=tfm1\Xxx\dependencyxxxpath, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=True, CustomTag= "; Assert.Equal(expectedFlatHierarchy, ((TestProjectTree)resultTree).FlatHierarchy); }
/// <summary> /// Builds Dependencies tree for given dependencies snapshot /// </summary> public override IProjectTree BuildTree( IProjectTree dependenciesTree, IDependenciesSnapshot snapshot, CancellationToken cancellationToken = default(CancellationToken)) { var originalTree = dependenciesTree; var currentTopLevelNodes = new List <IProjectTree>(); Func <IProjectTree, IEnumerable <IProjectTree>, IProjectTree> rememberNewNodes = (rootNode, currentNodes) => { if (currentNodes != null) { currentTopLevelNodes.AddRange(currentNodes); } return(rootNode); }; if (snapshot.Targets.Where(x => !x.Key.Equals(TargetFramework.Any)).Count() == 1) { foreach (var target in snapshot.Targets) { if (cancellationToken.IsCancellationRequested) { return(originalTree); } dependenciesTree = BuildSubTrees( dependenciesTree, snapshot.ActiveTarget, target.Value, target.Value.Catalogs, rememberNewNodes); } } else { foreach (var target in snapshot.Targets) { if (cancellationToken.IsCancellationRequested) { return(originalTree); } if (target.Key.Equals(TargetFramework.Any)) { dependenciesTree = BuildSubTrees(dependenciesTree, snapshot.ActiveTarget, target.Value, target.Value.Catalogs, rememberNewNodes); } else { var node = dependenciesTree.FindNodeByCaption(target.Key.FriendlyName); var shouldAddTargetNode = node == null; var targetViewModel = ViewModelFactory.CreateTargetViewModel(target.Value); node = CreateOrUpdateNode(node, targetViewModel, rule: null, isProjectItem: false, additionalFlags: ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp)); node = BuildSubTrees(node, snapshot.ActiveTarget, target.Value, target.Value.Catalogs, CleanupOldNodes); if (shouldAddTargetNode) { dependenciesTree = dependenciesTree.Add(node).Parent; } else { dependenciesTree = node.Parent; } currentTopLevelNodes.Add(node); } } } dependenciesTree = CleanupOldNodes(dependenciesTree, currentTopLevelNodes); // now update root Dependencies node status var rootIcon = ViewModelFactory.GetDependenciesRootIcon(snapshot.HasUnresolvedDependency).ToProjectSystemType(); return(dependenciesTree.SetProperties(icon: rootIcon, expandedIcon: rootIcon)); }
/// <summary> /// Builds all available sub trees under root: target framework or Dependencies node /// when there is only one target. /// </summary> private IProjectTree BuildSubTrees( IProjectTree rootNode, ITargetFramework activeTarget, ITargetedDependenciesSnapshot targetedSnapshot, IProjectCatalogSnapshot catalogs, Func <IProjectTree, IEnumerable <IProjectTree>, IProjectTree> syncFunc) { var currentNodes = new List <IProjectTree>(); var grouppedByProviderType = new Dictionary <string, List <IDependency> >(StringComparer.OrdinalIgnoreCase); foreach (var dependency in targetedSnapshot.TopLevelDependencies) { if (!dependency.Visible) { if (dependency.Flags.Contains(DependencyTreeFlags.ShowEmptyProviderRootNode)) { // if provider sends special invisible node with flag ShowEmptyProviderRootNode, we // need to show provider node even if it does not have any dependencies. grouppedByProviderType.Add(dependency.ProviderType, new List <IDependency>()); } continue; } if (!grouppedByProviderType.TryGetValue(dependency.ProviderType, out List <IDependency> dependencies)) { dependencies = new List <IDependency>(); grouppedByProviderType.Add(dependency.ProviderType, dependencies); } dependencies.Add(dependency); } var isActiveTarget = targetedSnapshot.TargetFramework.Equals(activeTarget); foreach (var dependencyGroup in grouppedByProviderType) { var subTreeViewModel = ViewModelFactory.CreateRootViewModel( dependencyGroup.Key, targetedSnapshot.CheckForUnresolvedDependencies(dependencyGroup.Key)); var subTreeNode = rootNode.FindNodeByCaption(subTreeViewModel.Caption); var isNewSubTreeNode = subTreeNode == null; var excludedFlags = ProjectTreeFlags.Empty; if (targetedSnapshot.TargetFramework.Equals(TargetFramework.Any)) { excludedFlags = ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp); } subTreeNode = CreateOrUpdateNode( subTreeNode, subTreeViewModel, rule: null, isProjectItem: false, excludedFlags: excludedFlags); subTreeNode = BuildSubTree( subTreeNode, targetedSnapshot, dependencyGroup.Value, catalogs, isActiveTarget, shouldCleanup: !isNewSubTreeNode); currentNodes.Add(subTreeNode); if (isNewSubTreeNode) { rootNode = rootNode.Add(subTreeNode).Parent; } else { rootNode = subTreeNode.Parent; } } return(syncFunc(rootNode, currentNodes)); }
public void Matches_MultipleFlags(string s, bool expected) { var detector = new FlagsStringMatcher(ProjectTreeFlags.Create("APPLE") + ProjectTreeFlags.Create("BANANA")); Assert.Equal(expected, detector.Matches(s)); }
public static ProjectTreeFlags CreateNewProjectRoot() => ProjectTreeFlags.Create(ProjectTreeFlags.Common.ProjectRoot);