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); }
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); }
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); }
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); } }
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(); }
/// <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); } }