protected abstract void ProcessInputNode(
     IGraphContext graphContext,
     GraphNode inputGraphNode,
     IDependency dependency,
     IDependenciesSnapshot snapshot,
     IDependenciesGraphViewProvider viewProvider,
     string projectPath,
     ref bool trackChanges);
        public override bool HandleChanges(IGraphContext graphContext, SnapshotChangedEventArgs e)
        {
            IDependenciesSnapshot snapshot = e.Snapshot;

            if (snapshot == null || e.Token.IsCancellationRequested)
            {
                return(false);
            }

            foreach (GraphNode inputGraphNode in graphContext.InputNodes.ToList())
            {
                string existingDependencyId = inputGraphNode.GetValue <string>(DependenciesGraphSchema.DependencyIdProperty);
                if (string.IsNullOrEmpty(existingDependencyId))
                {
                    continue;
                }

                string projectPath = inputGraphNode.Id.GetValue(CodeGraphNodeIdName.Assembly);
                if (string.IsNullOrEmpty(projectPath))
                {
                    continue;
                }

                IDependency updatedDependency = GetDependency(projectPath, existingDependencyId, out IDependenciesSnapshot updatedSnapshot);
                if (updatedDependency == null)
                {
                    continue;
                }

                IDependenciesGraphViewProvider viewProvider = ViewProviders
                                                              .FirstOrDefaultValue((x, d) => x.SupportsDependency(d), updatedDependency);
                if (viewProvider == null)
                {
                    continue;
                }

                if (!viewProvider.ShouldTrackChanges(projectPath, snapshot.ProjectPath, updatedDependency))
                {
                    continue;
                }

                using (var scope = new GraphTransactionScope())
                {
                    viewProvider.TrackChanges(
                        graphContext,
                        projectPath,
                        updatedDependency,
                        inputGraphNode,
                        updatedSnapshot.Targets[updatedDependency.TargetFramework]);

                    scope.Complete();
                }
            }

            return(false);
        }
예제 #3
0
        public override bool HandleRequest(IGraphContext graphContext)
        {
            bool trackChanges = false;

            foreach (GraphNode inputGraphNode in graphContext.InputNodes)
            {
                if (graphContext.CancelToken.IsCancellationRequested)
                {
                    return(trackChanges);
                }

                string projectPath = inputGraphNode.Id.GetValue(CodeGraphNodeIdName.Assembly);
                if (string.IsNullOrEmpty(projectPath))
                {
                    continue;
                }

                IDependency dependency = GetDependency(inputGraphNode, out IDependenciesSnapshot snapshot);
                if (dependency == null || snapshot == null)
                {
                    continue;
                }

                IDependenciesGraphViewProvider viewProvider = ViewProviders
                                                              .FirstOrDefaultValue((x, d) => x.SupportsDependency(d), dependency);

                if (viewProvider == null)
                {
                    continue;
                }

                if (graphContext.TrackChanges)
                {
                    trackChanges = true;
                }

                using (var scope = new GraphTransactionScope())
                {
                    viewProvider.BuildGraph(
                        graphContext,
                        projectPath,
                        dependency,
                        inputGraphNode,
                        snapshot.Targets[dependency.TargetFramework]);

                    scope.Complete();
                }
            }

            return(trackChanges);
        }
        public sealed override bool TryHandleRequest(IGraphContext graphContext)
        {
            if (!CanHandle(graphContext))
            {
                return(false);
            }

            bool trackChanges = false;

            foreach (GraphNode inputGraphNode in graphContext.InputNodes)
            {
                if (graphContext.CancelToken.IsCancellationRequested)
                {
                    return(trackChanges);
                }

                string projectPath = inputGraphNode.Id.GetValue(CodeGraphNodeIdName.Assembly);

                if (string.IsNullOrEmpty(projectPath))
                {
                    continue;
                }

                IDependency dependency = FindDependency(inputGraphNode, out IDependenciesSnapshot snapshot);

                if (dependency == null || snapshot == null)
                {
                    continue;
                }

                IDependenciesGraphViewProvider viewProvider = FindViewProvider(dependency);

                if (viewProvider == null)
                {
                    continue;
                }

                using (var scope = new GraphTransactionScope())
                {
                    ProcessInputNode(graphContext, inputGraphNode, dependency, snapshot, viewProvider, projectPath, ref trackChanges);

                    scope.Complete();
                }
            }

            return(trackChanges);
        }
예제 #5
0
        public override bool HandleRequest(IGraphContext graphContext)
        {
            foreach (GraphNode inputGraphNode in graphContext.InputNodes)
            {
                if (graphContext.CancelToken.IsCancellationRequested)
                {
                    return(false);
                }

                string projectPath = inputGraphNode.Id.GetValue(CodeGraphNodeIdName.Assembly);
                if (string.IsNullOrEmpty(projectPath))
                {
                    continue;
                }

                IDependency dependency = GetDependency(inputGraphNode, out IDependenciesSnapshot snapshot);
                if (dependency == null || snapshot == null)
                {
                    continue;
                }

                IDependenciesGraphViewProvider viewProvider = ViewProviders
                                                              .FirstOrDefaultValue((x, d) => x.SupportsDependency(d), dependency);

                if (viewProvider == null)
                {
                    continue;
                }

                using (var scope = new GraphTransactionScope())
                {
                    inputGraphNode.SetValue(DependenciesGraphSchema.DependencyIdProperty, dependency.Id);
                    inputGraphNode.SetValue(DependenciesGraphSchema.ResolvedProperty, dependency.Resolved);

                    if (viewProvider.HasChildren(projectPath, dependency))
                    {
                        inputGraphNode.SetValue(DgmlNodeProperties.ContainsChildren, true);
                    }

                    scope.Complete();
                }
            }

            return(false);
        }
예제 #6
0
        protected override void ProcessInputNode(IGraphContext graphContext, GraphNode inputGraphNode, IDependency dependency, DependenciesSnapshot snapshot, IDependenciesGraphViewProvider viewProvider, string projectPath, ref bool trackChanges)
        {
            inputGraphNode.SetValue(DependenciesGraphSchema.DependencyIdProperty, dependency.Id);
            inputGraphNode.SetValue(DependenciesGraphSchema.ResolvedProperty, dependency.Resolved);

            if (viewProvider.HasChildren(dependency))
            {
                inputGraphNode.SetValue(DgmlNodeProperties.ContainsChildren, true);
            }
        }
예제 #7
0
        protected override void ProcessInputNode(IGraphContext graphContext, GraphNode inputGraphNode, IDependency dependency, IDependenciesSnapshot snapshot, IDependenciesGraphViewProvider viewProvider, string projectPath, ref bool trackChanges)
        {
            if (graphContext.TrackChanges)
            {
                trackChanges = true;
            }

            viewProvider.BuildGraph(
                graphContext,
                projectPath,
                dependency,
                inputGraphNode,
                snapshot.Targets[dependency.TargetFramework]);
        }
        /// <summary>
        /// Generates search graph containing nodes matching search criteria in Solution Explorer
        /// and attaches it to correct top level node.
        /// </summary>
        private void Search(IGraphContext graphContext)
        {
            string searchParametersTypeName            = typeof(ISolutionSearchParameters).GUID.ToString();
            ISolutionSearchParameters searchParameters = graphContext.GetValue <ISolutionSearchParameters>(searchParametersTypeName);

            string searchTerm = searchParameters?.SearchQuery.SearchString?.ToLowerInvariant();

            if (searchTerm == null)
            {
                return;
            }

            var cachedDependencyToMatchingResultsMap = new Dictionary <string, HashSet <IDependency> >(StringComparer.OrdinalIgnoreCase);
            var searchResultsPerContext = new Dictionary <string, HashSet <IDependency> >(StringComparer.OrdinalIgnoreCase);

            System.Collections.Generic.IReadOnlyCollection <IDependenciesSnapshotProvider> snapshotProviders = AggregateSnapshotProvider.GetSnapshotProviders();
            foreach (IDependenciesSnapshotProvider snapshotProvider in snapshotProviders)
            {
                IDependenciesSnapshot snapshot = snapshotProvider.CurrentSnapshot;
                if (snapshot == null)
                {
                    continue;
                }

                searchResultsPerContext[snapshotProvider.ProjectFilePath] = SearchFlat(
                    searchTerm.ToLowerInvariant(),
                    snapshot);
            }

            foreach (IDependenciesSnapshotProvider snapshotProvider in snapshotProviders)
            {
                IDependenciesSnapshot snapshot = snapshotProvider.CurrentSnapshot;
                if (snapshot == null)
                {
                    continue;
                }

                IEnumerable <IDependency> allTopLevelDependencies = snapshot.GetFlatTopLevelDependencies();
                HashSet <IDependency>     matchedDependencies     = searchResultsPerContext[snapshotProvider.ProjectFilePath];

                using (var scope = new GraphTransactionScope())
                {
                    foreach (IDependency topLevelDependency in allTopLevelDependencies)
                    {
                        ITargetedDependenciesSnapshot targetedSnapshot = snapshot.Targets[topLevelDependency.TargetFramework];

                        if (!cachedDependencyToMatchingResultsMap
                            .TryGetValue(topLevelDependency.Id, out HashSet <IDependency> topLevelDependencyMatches))
                        {
                            IDependenciesGraphViewProvider viewProvider = ViewProviders
                                                                          .FirstOrDefaultValue((x, d) => x.SupportsDependency(d), topLevelDependency);

                            if (viewProvider == null)
                            {
                                continue;
                            }

                            bool processed = viewProvider.MatchSearchResults(
                                snapshotProvider.ProjectFilePath,
                                topLevelDependency,
                                searchResultsPerContext,
                                out topLevelDependencyMatches);

                            if (!processed)
                            {
                                if (matchedDependencies.Count == 0)
                                {
                                    continue;
                                }

                                topLevelDependencyMatches = GetMatchingResultsForDependency(
                                    topLevelDependency,
                                    targetedSnapshot,
                                    matchedDependencies,
                                    cachedDependencyToMatchingResultsMap);
                            }

                            cachedDependencyToMatchingResultsMap[topLevelDependency.Id] = topLevelDependencyMatches;
                        }

                        if (topLevelDependencyMatches.Count == 0)
                        {
                            continue;
                        }

                        GraphNode topLevelNode = Builder.AddTopLevelGraphNode(graphContext,
                                                                              snapshotProvider.ProjectFilePath,
                                                                              topLevelDependency.ToViewModel(targetedSnapshot));
                        foreach (IDependency matchedDependency in topLevelDependencyMatches)
                        {
                            GraphNode matchedDependencyNode = Builder.AddGraphNode(graphContext,
                                                                                   snapshotProvider.ProjectFilePath,
                                                                                   topLevelNode,
                                                                                   matchedDependency.ToViewModel(targetedSnapshot));

                            graphContext.Graph.Links.GetOrCreate(topLevelNode,
                                                                 matchedDependencyNode,
                                                                 label: null,
                                                                 GraphCommonSchema.Contains);
                        }

                        if (topLevelNode != null)
                        {
                            // 'node' is a GraphNode for top level dependency (which is part of solution explorer tree)
                            // Setting ProjectItem category (and correct GraphNodeId) ensures that search graph appears
                            // under right solution explorer hierarchy item
                            topLevelNode.AddCategory(CodeNodeCategories.ProjectItem);
                        }
                    }

                    scope.Complete();
                }
            }

            graphContext.OnCompleted();
        }
예제 #9
0
        /// <summary>
        /// ProjectContextChanged gets fired every time dependencies change for projects across solution.
        /// <see cref="_expandedGraphContexts"/> contains all nodes that we need to check for potential updates
        /// in their child dependencies.
        /// </summary>
        private void OnSnapshotChanged(object sender, SnapshotChangedEventArgs e)
        {
            IDependenciesSnapshot snapshot = e.Snapshot;

            if (snapshot == null || e.Token.IsCancellationRequested)
            {
                return;
            }

            // _expandedGraphContexts remembers graph expanded or checked so far.
            // Each context represents one level in the graph, i.e. a node and its first level dependencies
            // Tracking changes over all expanded contexts ensures that all levels are processed
            // and updated when there are any changes in nodes data.
            lock (_lock)
            {
                foreach (IGraphContext graphContext in _expandedGraphContexts)
                {
                    if (e.Token.IsCancellationRequested)
                    {
                        return;
                    }

                    bool anyChanges = false;

                    try
                    {
                        if (HandleChanges(graphContext))
                        {
                            anyChanges = true;
                        }
                    }
                    finally
                    {
                        // Calling OnCompleted ensures that the changes are reflected in UI
                        if (anyChanges)
                        {
                            graphContext.OnCompleted();
                        }
                    }
                }
            }

            return;

            bool HandleChanges(IGraphContext graphContext)
            {
                bool anyChanges = false;

                foreach (GraphNode inputGraphNode in graphContext.InputNodes.ToList())
                {
                    string existingDependencyId = inputGraphNode.GetValue <string>(DependenciesGraphSchema.DependencyIdProperty);
                    if (string.IsNullOrEmpty(existingDependencyId))
                    {
                        continue;
                    }

                    string nodeProjectPath = inputGraphNode.Id.GetValue(CodeGraphNodeIdName.Assembly);
                    if (string.IsNullOrEmpty(nodeProjectPath))
                    {
                        continue;
                    }

                    IDependenciesSnapshot updatedSnapshot = _aggregateSnapshotProvider.GetSnapshot(nodeProjectPath);

                    IDependency updatedDependency = updatedSnapshot?.FindDependency(existingDependencyId);

                    if (updatedDependency == null)
                    {
                        continue;
                    }

                    IDependenciesGraphViewProvider viewProvider = _viewProviders
                                                                  .FirstOrDefaultValue((x, d) => x.SupportsDependency(d), updatedDependency);
                    if (viewProvider == null)
                    {
                        continue;
                    }

                    if (!viewProvider.ShouldApplyChanges(nodeProjectPath, snapshot.ProjectPath, updatedDependency))
                    {
                        continue;
                    }

                    using (var scope = new GraphTransactionScope())
                    {
                        if (viewProvider.ApplyChanges(
                                graphContext,
                                nodeProjectPath,
                                updatedDependency,
                                inputGraphNode,
                                updatedSnapshot.Targets[updatedDependency.TargetFramework]))
                        {
                            anyChanges = true;
                        }

                        scope.Complete();
                    }
                }

                return(anyChanges);
            }
        }