internal async Task BeginGetGraphDataAsync(IGraphContext context) { try { await EnsureInitializedAsync().ConfigureAwait(false); if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) { await CheckChildrenAsync(context).ConfigureAwait(false); } else if (context.Direction == GraphContextDirection.Contains) { await GetChildrenAsync(context).ConfigureAwait(false); } else if (context.Direction == GraphContextDirection.Custom) { await SearchAsync(context).ConfigureAwait(false); } } finally { // OnCompleted must be called to display changes context.OnCompleted(); } }
private void SearchNextItem(string term, IGraphContext context) { if (context.CancelToken.IsCancellationRequested || string.IsNullOrEmpty(term)) { // stop right here, no more calls and empty the queue. this.searchItems = null; return; } IItemNode item; if (this.searchItems != null && this.searchItems.TryDequeue(out item)) { var normalizedTerm = term.ToLowerInvariant(); var installedPackages = GetInstalledPackages(item.PhysicalPath) .Where(x => x.Id.ToLowerInvariant().Contains(normalizedTerm)) .ToList(); tracer.Info("Found {0} packages installed matching {1} on package file {2}", installedPackages.Count, normalizedTerm, item.PhysicalPath); AddPackageNodes(context, () => this.GetOrCreateConfigNode(context, item), installedPackages, false); Application.Current.Dispatcher.BeginInvoke(new Action <string, IGraphContext>(SearchNextItem), term, context); } else { context.OnCompleted(); } }
public void BeginGetGraphData(IGraphContext context) { if (context.CancelToken.IsCancellationRequested) { return; } switch (context.Direction) { case GraphContextDirection.Self: { if (context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) { Prepare(context); } break; } case GraphContextDirection.Contains: { Prepare(context); TryPopulatePaketNode(context); break; } case GraphContextDirection.Custom: break; } context.OnCompleted(); }
internal async Task BeginGetGraphDataAsync(IGraphContext context) { try { await InitializeAsync(); IEnumerable <Lazy <IDependenciesGraphActionHandler, IOrderPrecedenceMetadataView> > actionHandlers = GraphActionHandlers.Where(x => x.Value.CanHandleRequest(context)); bool shouldTrackChanges = actionHandlers.Aggregate( false, (previousTrackFlag, handler) => previousTrackFlag || handler.Value.HandleRequest(context)); if (!shouldTrackChanges) { return; } lock (_expandedGraphContextsLock) { if (!ExpandedGraphContexts.Contains(context)) { // Remember this graph context in order to track changes. // When references change, we will adjust children of this graph as necessary ExpandedGraphContexts.Add(context); } } } finally { // OnCompleted must be called to display changes context.OnCompleted(); } }
/// <summary> /// Entry point for progression. Gets called every time when progression /// - Needs to know if a node has children /// - Wants to get children for a node /// - During solution explorer search /// </summary> public void BeginGetGraphData(IGraphContext context) { JoinableFactory.RunAsync(async() => { try { await InitializeAsync(); foreach (Lazy <IDependenciesGraphActionHandler, IOrderPrecedenceMetadataView> handler in _graphActionHandlers) { if (handler.Value.TryHandleRequest(context)) { _changeTracker.RegisterGraphContext(context); // Only one handler should succeed return; } } } catch (Exception ex) { context.ReportError(ex); } finally { // OnCompleted must be called to display changes context.OnCompleted(); } }); }
private void CreateChildren(object state) { IGraphContext context = (IGraphContext)state; using (GraphTransactionScope scope = new GraphTransactionScope()) { foreach (var node in context.InputNodes.Where(n => n.HasCategory(CssGraphSchema.CssAtDirectivesParent))) { CreateChild <AtDirective>(context, node, CssGraphSchema.CssAtDirectives); context.ReportProgress(1, 3, null); } foreach (var node in context.InputNodes.Where(n => n.HasCategory(CssGraphSchema.CssIdSelectorParent))) { CreateChild <IdSelector>(context, node, CssGraphSchema.CssIdSelector); context.ReportProgress(2, 3, null); } foreach (var node in context.InputNodes.Where(n => n.HasCategory(CssGraphSchema.CssClassSelectorParent))) { CreateChild <ClassSelector>(context, node, CssGraphSchema.CssClassSelector); context.ReportProgress(3, 3, null); } scope.Complete(); } context.OnCompleted(); }
internal async Task BeginGetGraphDataAsync(IGraphContext context) { try { await InitializeAsync().ConfigureAwait(false); var actionHandlers = GraphActionHandlers.Where(x => x.Value.CanHandleRequest(context)); var shouldTrackChanges = actionHandlers.Aggregate( false, (previousTrackFlag, handler) => previousTrackFlag || handler.Value.HandleRequest(context)); lock (_expandedGraphContextsLock) { if (shouldTrackChanges && !ExpandedGraphContexts.Contains(context)) { // Remember this graph context in order to track changes. // When references change, we will adjust children of this graph as necessary ExpandedGraphContexts.Add(context); } } } finally { // OnCompleted must be called to display changes context.OnCompleted(); } }
public void BeginGetGraphData(IGraphContext context) { if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) { MarkThatNodesHaveChildren(context); } else if (context.Direction == GraphContextDirection.Self || (context.Direction == GraphContextDirection.Contains && context.NodeCategories.Any(c => c.IsBasedOn(MarkdownSchema.Heading)))) { PopulateChildrenOfNodes(context); } context.OnCompleted(); }
public void BeginGetGraphData(IGraphContext context) { EnsureInitialized(); var graphQueries = GetGraphQueries(context); if (graphQueries.Count > 0) { _graphQueryManager.AddQueries(context, graphQueries); } else { // It's an unknown query type, so we're done context.OnCompleted(); } }
private void BeginGetGraphData(IGraphContext context, bool queueUserWorkItem) { if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) { var configNode = context.InputNodes.FirstOrDefault(node => node.IsConfigNode()); if (configNode != null) { using (var scope = new GraphTransactionScope()) { configNode.SetValue(DgmlNodeProperties.ContainsChildren, true); scope.Complete(); } } } else if (context.Direction == GraphContextDirection.Contains) { var configNode = context.InputNodes.FirstOrDefault(node => node.IsConfigNode()); if (configNode != null) { if (queueUserWorkItem) { ThreadPool.QueueUserWorkItem(TryAddPackageNodes, context); } else { TryAddPackageNodes(context); } // Prevent OnCompleted since we're either doing it // async or synchronously and completing in AddPackageNodes. return; } } else if (context.Direction == GraphContextDirection.Custom) { StartSearch(context); return; } context.OnCompleted(); }
internal void AddQueries(IGraphContext context, List<IGraphQuery> graphQueries) { var asyncToken = _asyncListener.BeginAsyncOperation("GraphQueryManager.AddQueries"); var solution = _workspace.CurrentSolution; var populateTask = PopulateContextGraphAsync(solution, graphQueries, context); // We want to ensure that no matter what happens, this initial context is completed var task = populateTask.SafeContinueWith( _ => context.OnCompleted(), context.CancelToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); if (context.TrackChanges) { task = task.SafeContinueWith( _ => TrackChangesAfterFirstPopulate(graphQueries, context, solution), context.CancelToken, TaskContinuationOptions.None, TaskScheduler.Default); } task.CompletesAsyncOperation(asyncToken); }
internal void AddQueries(IGraphContext context, List <IGraphQuery> graphQueries) { var asyncToken = _asyncListener.BeginAsyncOperation("GraphQueryManager.AddQueries"); var solution = _workspace.CurrentSolution; var populateTask = PopulateContextGraphAsync(solution, graphQueries, context); // We want to ensure that no matter what happens, this initial context is completed var task = populateTask.SafeContinueWith( _ => context.OnCompleted(), context.CancelToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); if (context.TrackChanges) { task = task.SafeContinueWith( _ => TrackChangesAfterFirstPopulate(graphQueries, context, solution), context.CancelToken, TaskContinuationOptions.None, TaskScheduler.Default); } task.CompletesAsyncOperation(asyncToken); }
public override void BeginGetGraphData(IGraphContext context) { RegisterImages(); if (context.Direction == GraphContextDirection.Contains) { CreateOutline(context); if (context.TrackChanges) { ThreadPool.QueueUserWorkItem(CreateChildren, context); } else { CreateChildren(context); } return; // Don't call OnCompleted } else if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) { foreach (GraphNode node in GetAllowedFiles(context.InputNodes)) { node.SetValue(DgmlNodeProperties.ContainsChildren, true); } foreach (var node in context.InputNodes.Where(n => n.HasCategory(CssGraphSchema.CssAtDirectivesParent) || n.HasCategory(CssGraphSchema.CssIdSelectorParent) || n.HasCategory(CssGraphSchema.CssClassSelectorParent) )) { node.SetValue(DgmlNodeProperties.ContainsChildren, true); } } // Signals that all results have been created. context.OnCompleted(); }
internal async Task BeginGetGraphDataAsync(IGraphContext context) { try { await InitializeAsync(); bool shouldTrackChanges = false; foreach (Lazy <IDependenciesGraphActionHandler, IOrderPrecedenceMetadataView> handler in _graphActionHandlers) { if (handler.Value.CanHandleRequest(context) && handler.Value.HandleRequest(context)) { shouldTrackChanges = true; break; } } if (!shouldTrackChanges) { return; } lock (_expandedGraphContexts) { if (!_expandedGraphContexts.Contains(context)) { // Remember this graph context in order to track changes. // When references change, we will adjust children of this graph as necessary _expandedGraphContexts.Add(context); } } } finally { // OnCompleted must be called to display changes context.OnCompleted(); } }
private void CreateChildren(object state) { IGraphContext context = (IGraphContext)state; using (GraphTransactionScope scope = new GraphTransactionScope()) { foreach (var node in context.InputNodes.Where(n => n.HasCategory(LessGraphSchema.LessMixinParent))) { CreateChild <LessMixinDeclaration>(context, node, LessGraphSchema.LessMixin); context.ReportProgress(1, 2, null); } foreach (var node in context.InputNodes.Where(n => n.HasCategory(LessGraphSchema.LessVariableParent))) { CreateChild <LessVariableDeclaration>(context, node, LessGraphSchema.LessVariable); context.ReportProgress(2, 2, null); } scope.Complete(); } context.OnCompleted(); }
/// <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; 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 <IDependenciesSnapshot> snapshots = AggregateSnapshotProvider.GetSnapshots(); foreach (IDependenciesSnapshot snapshot in snapshots) { searchResultsPerContext[snapshot.ProjectPath] = SearchFlat( searchTerm, snapshot); } foreach (IDependenciesSnapshot snapshot in snapshots) { IEnumerable <IDependency> allTopLevelDependencies = snapshot.GetFlatTopLevelDependencies(); HashSet <IDependency> matchedDependencies = searchResultsPerContext[snapshot.ProjectPath]; using var scope = new GraphTransactionScope(); foreach (IDependency topLevelDependency in allTopLevelDependencies) { ITargetedDependenciesSnapshot targetedSnapshot = snapshot.DependenciesByTargetFramework[topLevelDependency.TargetFramework]; if (!cachedDependencyToMatchingResultsMap .TryGetValue(topLevelDependency.Id, out HashSet <IDependency>?topLevelDependencyMatches)) { IDependenciesGraphViewProvider?viewProvider = FindViewProvider(topLevelDependency); if (viewProvider == null) { continue; } if (!viewProvider.MatchSearchResults( topLevelDependency, searchResultsPerContext, out topLevelDependencyMatches)) { 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, snapshot.ProjectPath, topLevelDependency.ToViewModel(targetedSnapshot)); foreach (IDependency matchedDependency in topLevelDependencyMatches) { GraphNode matchedDependencyNode = _builder.AddGraphNode(graphContext, snapshot.ProjectPath, 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> /// Generates search graph containing nodes matching search criteria in Solution Explorer /// and attaches it to correct top level node. /// </summary> private async Task SearchAsync(IGraphContext graphContext) { var searchParametersTypeName = typeof(ISolutionSearchParameters).GUID.ToString(); var searchParameters = graphContext.GetValue <ISolutionSearchParameters>(searchParametersTypeName); if (searchParameters == null) { return; } var searchTerm = searchParameters.SearchQuery.SearchString?.ToLowerInvariant(); if (searchTerm == null) { return; } var projectContexts = ProjectContextProvider.GetProjectContexts(); foreach (var projectContext in projectContexts) { var subTreeProviders = projectContext.GetProviders(); foreach (var subTreeProvider in subTreeProviders) { await RegisterSubTreeProviderAsync(subTreeProvider, graphContext).ConfigureAwait(false); foreach (var topLevelNode in subTreeProvider.RootNode.Children) { var refreshedTopLevelNode = subTreeProvider.GetDependencyNode(topLevelNode.Id); if (refreshedTopLevelNode == null) { continue; } var matchingNodes = await subTreeProvider.SearchAsync(refreshedTopLevelNode, searchTerm).ConfigureAwait(true); if (matchingNodes == null || matchingNodes.Count() <= 0) { continue; } // Note: scope should start and complete on the same thread, so we have to do it for each provider. using (var scope = new GraphTransactionScope()) { // add provider's root node to display matching nodes var topLevelGraphNode = AddTopLevelGraphNode(graphContext, projectContext.ProjectFilePath, subTreeProvider, nodeInfo: refreshedTopLevelNode); // now recursively add graph nodes for provider nodes that match search criteria under // provider's root node AddNodesToGraphRecursive(graphContext, projectContext.ProjectFilePath, subTreeProvider, topLevelGraphNode, matchingNodes); // '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 topLevelGraphNode.AddCategory(CodeNodeCategories.ProjectItem); scope.Complete(); } } } } graphContext.OnCompleted(); }
public void BeginGetGraphData(IGraphContext context) { EnsureInitialized(); var graphQueries = new List <IGraphQuery>(); if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) { graphQueries.Add(new ContainsChildrenGraphQuery()); } if (context.Direction == GraphContextDirection.Contains) { graphQueries.Add(new ContainsGraphQuery()); } if (context.LinkCategories.Contains(CodeLinkCategories.InheritsFrom)) { if (context.Direction == GraphContextDirection.Target) { graphQueries.Add(new InheritsGraphQuery()); } else if (context.Direction == GraphContextDirection.Source) { graphQueries.Add(new InheritedByGraphQuery()); } } if (context.LinkCategories.Contains(CodeLinkCategories.SourceReferences)) { graphQueries.Add(new IsUsedByGraphQuery()); } if (context.LinkCategories.Contains(CodeLinkCategories.Calls)) { if (context.Direction == GraphContextDirection.Target) { graphQueries.Add(new CallsGraphQuery()); } else if (context.Direction == GraphContextDirection.Source) { graphQueries.Add(new IsCalledByGraphQuery()); } } if (context.LinkCategories.Contains(CodeLinkCategories.Implements)) { if (context.Direction == GraphContextDirection.Target) { graphQueries.Add(new ImplementsGraphQuery()); } else if (context.Direction == GraphContextDirection.Source) { graphQueries.Add(new ImplementedByGraphQuery()); } } if (context.LinkCategories.Contains(RoslynGraphCategories.Overrides)) { if (context.Direction == GraphContextDirection.Source) { graphQueries.Add(new OverridesGraphQuery()); } else if (context.Direction == GraphContextDirection.Target) { graphQueries.Add(new OverriddenByGraphQuery()); } } if (context.Direction == GraphContextDirection.Custom) { var searchParameters = context.GetValue <ISolutionSearchParameters>(typeof(ISolutionSearchParameters).GUID.ToString()); if (searchParameters != null) { // WARNING: searchParameters.SearchQuery returns an IVsSearchQuery object, which // is a COM type. Therefore, it's probably best to grab the values we want now // rather than get surprised by COM marshalling later. graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString)); } } if (graphQueries.Count > 0) { _graphQueryManager.AddQueries(context, graphQueries); } else { // It's an unknown query type, so we're done context.OnCompleted(); } }
/// <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) { var searchParametersTypeName = typeof(ISolutionSearchParameters).GUID.ToString(); var searchParameters = graphContext.GetValue <ISolutionSearchParameters>(searchParametersTypeName); if (searchParameters == null) { return; } var 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); var snapshotProviders = AggregateSnapshotProvider.GetSnapshotProviders(); foreach (var snapshotProvider in snapshotProviders) { var snapshot = snapshotProvider.CurrentSnapshot; if (snapshot == null) { continue; } searchResultsPerContext[snapshotProvider.ProjectFilePath] = SearchFlat(snapshotProvider.ProjectFilePath, searchTerm.ToLowerInvariant(), graphContext, snapshot); } foreach (var snapshotProvider in snapshotProviders) { var snapshot = snapshotProvider.CurrentSnapshot; if (snapshot == null) { continue; } var allTopLevelDependencies = snapshot.GetFlatTopLevelDependencies(); var matchedDependencies = searchResultsPerContext[snapshotProvider.ProjectFilePath]; using (var scope = new GraphTransactionScope()) { foreach (var topLevelDependency in allTopLevelDependencies) { var targetedSnapshot = snapshot.Targets[topLevelDependency.TargetFramework]; if (!cachedDependencyToMatchingResultsMap .TryGetValue(topLevelDependency.Id, out HashSet <IDependency> topLevelDependencyMatches)) { var viewProvider = ViewProviders.FirstOrDefault(x => x.Value.SupportsDependency(topLevelDependency)); if (viewProvider == null) { continue; } var processed = viewProvider.Value.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; } var topLevelNode = Builder.AddTopLevelGraphNode(graphContext, snapshotProvider.ProjectFilePath, topLevelDependency.ToViewModel(targetedSnapshot)); foreach (var matchedDependency in topLevelDependencyMatches) { var matchedDependencyNode = Builder.AddGraphNode(graphContext, snapshotProvider.ProjectFilePath, topLevelNode, matchedDependency.ToViewModel(targetedSnapshot)); graphContext.Graph.Links.GetOrCreate(topLevelNode, matchedDependencyNode, null /*label*/, 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(); }
public override void BeginGetGraphData(IGraphContext context) { RegisterImages(); if (context.Direction == GraphContextDirection.Contains) { CreateOutline(context); if (context.TrackChanges) { ThreadPool.QueueUserWorkItem(CreateChildren, context); } else { CreateChildren(context); } return; } else if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) { foreach (GraphNode node in GetAllowedFiles(context.InputNodes)) { node.SetValue(DgmlNodeProperties.ContainsChildren, true); } foreach (var node in context.InputNodes.Where(n => n.HasCategory(LessGraphSchema.LessMixinParent) || n.HasCategory(LessGraphSchema.LessVariableParent) )) { node.SetValue(DgmlNodeProperties.ContainsChildren, true); } } // Signals that all results have been created. context.OnCompleted(); }