public async Task UpdateCapabilitiesAsync(ImmutableHashSet <string> capabilities, CancellationToken cancellationToken)
        {
            if (capabilities == null)
            {
                throw new ArgumentNullException(nameof(capabilities));
            }

            await ProjectLockService.WriteLockAsync((releaser) =>
            {
                _capabilities = capabilities;
                Refresh();
            }, cancellationToken);
        }
Exemple #2
0
        public override async void UpdateProjectAsync(ProjectUpdateAction update)
        {
            using (var access = await ProjectLockService.WriteLockAsync())
            {
                var configuredProject = await UnconfiguredProject.GetSuggestedConfiguredProjectAsync();

                var project = await access.GetProjectAsync(configuredProject);

                //
                // Check out the project from SCC before aply any changes
                //
                await access.CheckoutAsync(configuredProject.UnconfiguredProject.FullPath);

                if (update(project))
                {
                    project.Save();
                }
            }
        }
        TResult ExecuteLockAction <TResult>(Func <Microsoft.Build.Evaluation.Project, TResult> callback, LockType lockType = LockType.Read, TResult defaultValue = default(TResult))
        {
            var context = ContainingProject as IVsBrowseObjectContext;

            if (context == null)
            {
                context = ContainingProject.Object as IVsBrowseObjectContext;
            }

            if (context != null)
            {
                return(AsyncManager.Run(async() =>
                {
                    if (lockType == LockType.Read)
                    {
                        using (var access = await ProjectLockService.ReadLockAsync())
                        {
                            var configuredProject = await context.UnconfiguredProject.GetSuggestedConfiguredProjectAsync();

                            var project = await access.GetProjectAsync(configuredProject);

                            return callback(project);
                        }
                    }
                    else
                    {
                        using (var access = await ProjectLockService.WriteLockAsync())
                        {
                            var configuredProject = await context.UnconfiguredProject.GetSuggestedConfiguredProjectAsync();

                            var project = await access.GetProjectAsync(configuredProject);

                            return callback(project);
                        }
                    }
                }));
            }

            return(defaultValue);
        }
        /// <summary>
        /// Deletes items from the project, and optionally from disk.
        /// Note: Delete and Remove commands are handled via IVsHierarchyDeleteHandler3, not by
        /// IAsyncCommandGroupHandler and first asks us we CanRemove nodes. If yes then RemoveAsync is called.
        /// We can remove only nodes that are standard and based on project items, i.e. nodes that
        /// are created by default IProjectDependenciesSubTreeProvider implementations and have
        /// DependencyNode.GenericDependencyFlags flags and IRule with Context != null, in order to obtain
        /// node's itemSpec. ItemSpec then used to remove a project item having same Include.
        /// </summary>
        /// <param name="nodes">The nodes that should be deleted.</param>
        /// <param name="deleteOptions">A value indicating whether the items should be deleted from disk as well as
        /// from the project file.
        /// </param>
        /// <exception cref="InvalidOperationException">Thrown when <see cref="IProjectTreeProvider.CanRemove"/>
        /// would return <c>false</c> for this operation.</exception>
        public override async Task RemoveAsync(IImmutableSet <IProjectTree> nodes,
                                               DeleteOptions deleteOptions = DeleteOptions.None)
        {
            if (deleteOptions.HasFlag(DeleteOptions.DeleteFromStorage))
            {
                throw new NotSupportedException();
            }

            // Get the list of shared import nodes.
            IEnumerable <IProjectTree> sharedImportNodes = nodes.Where(node =>
                                                                       node.Flags.Contains(ProjectTreeFlags.Common.SharedProjectImportReference));

            // Get the list of normal reference Item Nodes (this excludes any shared import nodes).
            IEnumerable <IProjectTree> referenceItemNodes = nodes.Except(sharedImportNodes);

            using (var access = await ProjectLockService.WriteLockAsync())
            {
                var project = await access.GetProjectAsync(ActiveConfiguredProject).ConfigureAwait(true);

                // Handle the removal of normal reference Item Nodes (this excludes any shared import nodes).
                foreach (var node in referenceItemNodes)
                {
                    if (node.BrowseObjectProperties == null || node.BrowseObjectProperties.Context == null)
                    {
                        // if node does not have an IRule with valid ProjectPropertiesContext we can not
                        // get it's itemsSpec. If nodes provided by custom IProjectDependenciesSubTreeProvider
                        // implementation, and have some custom IRule without context, it is not a problem,
                        // since they wouldnot have DependencyNode.GenericDependencyFlags and we would not
                        // end up here, since CanRemove would return false and Remove command would not show
                        // up for those nodes.
                        continue;
                    }

                    var nodeItemContext         = node.BrowseObjectProperties.Context;
                    var unresolvedReferenceItem = project.GetItemsByEvaluatedInclude(nodeItemContext.ItemName)
                                                  .FirstOrDefault(item => string.Equals(item.ItemType,
                                                                                        nodeItemContext.ItemType,
                                                                                        StringComparison.OrdinalIgnoreCase));

                    Report.IfNot(unresolvedReferenceItem != null, "Cannot find reference to remove.");
                    if (unresolvedReferenceItem != null)
                    {
                        await access.CheckoutAsync(unresolvedReferenceItem.Xml.ContainingProject.FullPath)
                        .ConfigureAwait(true);

                        project.RemoveItem(unresolvedReferenceItem);
                    }
                }

                // Handle the removal of shared import nodes.
                var projectXml = await access.GetProjectXmlAsync(UnconfiguredProject.FullPath)
                                 .ConfigureAwait(true);

                foreach (var sharedImportNode in sharedImportNodes)
                {
                    // Find the import that is included in the evaluation of the specified ConfiguredProject that
                    // imports the project file whose full path matches the specified one.
                    var matchingImports = from import in project.Imports
                                          where import.ImportingElement.ContainingProject == projectXml
                                          where PathHelper.IsSamePath(import.ImportedProject.FullPath,
                                                                      sharedImportNode.FilePath)
                                          select import;
                    foreach (var importToRemove in matchingImports)
                    {
                        var importingElementToRemove = importToRemove.ImportingElement;
                        Report.IfNot(importingElementToRemove != null,
                                     "Cannot find shared project reference to remove.");
                        if (importingElementToRemove != null)
                        {
                            await access.CheckoutAsync(importingElementToRemove.ContainingProject.FullPath)
                            .ConfigureAwait(true);

                            importingElementToRemove.Parent.RemoveChild(importingElementToRemove);
                        }
                    }
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Deletes items from the project, and optionally from disk.
        /// Note: Delete and Remove commands are handled via IVsHierarchyDeleteHandler3, not by
        /// IAsyncCommandGroupHandler and first asks us we CanRemove nodes. If yes then RemoveAsync is called.
        /// We can remove only nodes that are standard and based on project items, i.e. nodes that
        /// are created by default IProjectDependenciesSubTreeProvider implementations and have
        /// DependencyNode.GenericDependencyFlags flags and IRule with Context != null, in order to obtain
        /// node's itemSpec. ItemSpec then used to remove a project item having same Include.
        /// </summary>
        /// <param name="nodes">The nodes that should be deleted.</param>
        /// <param name="deleteOptions">A value indicating whether the items should be deleted from disk as well as
        /// from the project file.
        /// </param>
        /// <exception cref="InvalidOperationException">Thrown when <see cref="IProjectTreeProvider.CanRemove"/>
        /// would return <c>false</c> for this operation.</exception>
        public override async Task RemoveAsync(IImmutableSet <IProjectTree> nodes,
                                               DeleteOptions deleteOptions = DeleteOptions.None)
        {
            if (deleteOptions.HasFlag(DeleteOptions.DeleteFromStorage))
            {
                throw new NotSupportedException();
            }

            // Get the list of shared import nodes.
            IEnumerable <IProjectTree> sharedImportNodes = nodes.Where(node =>
                                                                       node.Flags.Contains(DependencyTreeFlags.SharedProjectFlags));

            // Get the list of normal reference Item Nodes (this excludes any shared import nodes).
            IEnumerable <IProjectTree> referenceItemNodes = nodes.Except(sharedImportNodes);

            await ProjectLockService.WriteLockAsync(async access =>
            {
                Project project = await access.GetProjectAsync(ActiveConfiguredProject);

                // Handle the removal of normal reference Item Nodes (this excludes any shared import nodes).
                foreach (IProjectTree node in referenceItemNodes)
                {
                    if (node.BrowseObjectProperties?.Context == null)
                    {
                        // if node does not have an IRule with valid ProjectPropertiesContext we can not
                        // get its itemsSpec. If nodes provided by custom IProjectDependenciesSubTreeProvider
                        // implementation, and have some custom IRule without context, it is not a problem,
                        // since they would not have DependencyNode.GenericDependencyFlags and we would not
                        // end up here, since CanRemove would return false and Remove command would not show
                        // up for those nodes.
                        continue;
                    }

                    IProjectPropertiesContext nodeItemContext = node.BrowseObjectProperties.Context;
                    ProjectItem unresolvedReferenceItem       = project.GetItemsByEvaluatedInclude(nodeItemContext.ItemName)
                                                                .FirstOrDefault(item => string.Equals(item.ItemType,
                                                                                                      nodeItemContext.ItemType,
                                                                                                      StringComparisons.ItemTypes));

                    Report.IfNot(unresolvedReferenceItem != null, "Cannot find reference to remove.");
                    if (unresolvedReferenceItem != null)
                    {
                        await access.CheckoutAsync(unresolvedReferenceItem.Xml.ContainingProject.FullPath);
                        project.RemoveItem(unresolvedReferenceItem);
                    }
                }

                IDependenciesSnapshot snapshot = _dependenciesSnapshotProvider.CurrentSnapshot;
                Requires.NotNull(snapshot, nameof(snapshot));
                if (snapshot == null)
                {
                    return;
                }

                // Handle the removal of shared import nodes.
                ProjectRootElement projectXml = await access.GetProjectXmlAsync(UnconfiguredProject.FullPath);
                foreach (IProjectTree sharedImportNode in sharedImportNodes)
                {
                    string sharedFilePath = UnconfiguredProject.GetRelativePath(sharedImportNode.FilePath);
                    if (string.IsNullOrEmpty(sharedFilePath))
                    {
                        continue;
                    }

                    IDependency sharedProjectDependency = snapshot.FindDependency(sharedFilePath, topLevel: true);
                    if (sharedProjectDependency != null)
                    {
                        sharedFilePath = sharedProjectDependency.Path;
                    }

                    // Find the import that is included in the evaluation of the specified ConfiguredProject that
                    // imports the project file whose full path matches the specified one.
                    IEnumerable <ResolvedImport> matchingImports = from import in project.Imports
                                                                   where import.ImportingElement.ContainingProject == projectXml &&
                                                                   PathHelper.IsSamePath(import.ImportedProject.FullPath, sharedFilePath)
                                                                   select import;
                    foreach (ResolvedImport importToRemove in matchingImports)
                    {
                        ProjectImportElement importingElementToRemove = importToRemove.ImportingElement;
                        Report.IfNot(importingElementToRemove != null,
                                     "Cannot find shared project reference to remove.");
                        if (importingElementToRemove != null)
                        {
                            await access.CheckoutAsync(importingElementToRemove.ContainingProject.FullPath);
                            importingElementToRemove.Parent.RemoveChild(importingElementToRemove);
                        }
                    }
                }
            });
        }